Delete ListView SelectedItem on Keypress - c#

I would like to have a Key press of the Delete Key to fire off a DelegateCommand to actually delete the selecteditem at that point.
I am having troubles finding the right syntax to do this. I am using the INotifyPropertyChanged Implementation to bind to public propreties on my ViewModel.
Is there a way to do this? Seems like there should be.
I have an
ObservableCollection<Object> Objects
lets say with fields in each Object (i.e. name, address)
Thanks for any help

To get a command to fire from a keypress:
<ListView ItemsSource="{Binding Path=Objects}" SelectedItem="{Binding Path=SelectedObject}">
<ListView.InputBindings>
<KeyBinding Key="Delete" Command="{Binding Path=MyCommand}"></KeyBinding>
</ListView.InputBindings>
</ListView>
For your selected item, have a property in your viewModel and bind the listView's SelectedItem to it.

You could use the 'event to command' feature in the MVVM Light Toolkit. By using this, you can set the keydown event to a command that gets fired in your ViewModel, along w/ the selected item's index as your param. Within your ViewModel, assuming your observablecollection is hooked up to your ListView right, you can then remove the selected item from the collection based on the index. Make sure the updatesourcetrigger on the items property of the listview is set to "property changed".

Related

TreeViewItem Command binding

I need to click on an TreeViewItem and open an dialog window with the data of that TreeViewItem, later based on that data I will run another command.
My actual problem is: I can't click on it because treeviewitem doesn't have the command property.
My scenario: I have 2 Models with 2 properties that will be used to create my TreeViewItems. On my ViewModel I create them, and organize them inside each other based on their properties and then store them inside One Collection.
Here's my xaml to bind the elements:
<TreeView ItemsSource="{Binding Local}">
<TreeView.DataContext>
<data:ItemViewModel/>
</TreeView.DataContext>
</Treeview>
//In my "Local" property I have 3 TreeViewItems with other items inside them which I want to execute the commands
I couldn't find a way to create a datatemplate for that specific scenario. Even tried to create a datatemplate with a Hyperlink (thought it would be a temporary solution) inside it, but would not execute any command.
MVVM pattern is to use one of the many "Event to Command" implementations out there. You basically bind the "Event to Command" object to the Click event and then a command in your VM gets bound to the "Event to Command" object and it gets mapped behind the scenes for you and handles all the enabled / disabled stuff.
You can see an example of one of the implementations here:
WPF Binding UI events to commands in ViewModel
You should be binding to a collection whose objects have a collection as a public property and templating by type into whatever you want to see in each treeviewitem.
Like this sample:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.hierarchicaldatatemplate?view=netframework-4.7.2
Technically, you could have a button whose template was a textblock or something and that would then have the behaviour of a button such as click and command.
But I'd be more likely to use an inputbinding.
Here's an example:
<DataTemplate DataType="{x:Type local:LineTerrainVM}">
<Grid Background="Transparent">
<Grid.InputBindings>
<MouseBinding MouseAction="RightClick" Command="{Binding FixLineCommand}"/>
</Grid.InputBindings>
You can give that a commandparameter="{Binding .}" and it'll pass the viewmodel as a parameter.
You could also use relativesource to the datacontext of the treeview to get at a parent viewmodel and define a command in that to do your stuff.
Since that stuff you want to do is a view responsibility you could rely on routed events without "breaking" mvvm. A click in any treeviewitem could be handled at the treeview level and use the originalsource to get to the treeviewitem clicked. Then grab it's datacontext for the viewmodel of whatever that is.
Rough idea:
<TreeView Name="tv" ItemsSource="{Binding Families}" FrameworkElement.PreviewMouseLeftButtonDown="Tv_PreviewMouseLeftButtonDown"
And the handler:
private void Tv_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var vm = ((FrameworkElement)e.OriginalSource).DataContext;
// do something with viewmodel
}
You could then do something like new up your dialog window, set it's datacontext to that viewmodel you just got and showdialog it.

Binding ObservableCollection to selected items of a ListBox

After hours and hours of googling, I still can't find a simple solution for binding an ObservableCollection to the selected items of a ListBox in a TwoWay Mode...
What I have is really simple : a ListBox with SelectionMode="Multiple", and an ObservableCollection<Contact> named SelectedContacts. I want this two to be bound. Of course my ListBox has ItemsSource="{Binding Contacts}" which is another ObservableCollection of Contact.
Now I really can't use a IsSelected bool on my Contact items, I just can't.
Thank you !
There is no simple solution. You can't bind SelectedItems.
The best solution is to select your Contact items into a view model object with an IsSelected property, bind to that, and then run a query against the primary OC when you need to get the selected items collection.
Since you said you can't/won't do that, the next best solution would likely be to handle SelectionChanged in your code-behind and manually update the VM collection from there.
Since SelectedItems is not a DependencyProperty you are not allowed to use Bindings
But there is a solution, take a look at this post:
http://blogs.microsoft.co.il/miziel/2014/05/02/wpf-binding-listbox-selecteditems-attached-property-vs-style/
Another option is to not keep track of the selected items in your ViewModel. Instead, pass them as a CommandParameter from the UI when you are trying to do some action.
Example:
<ListBox x:Name="MyListBox"
ItemsSource="{Binding SomeCollection}" />
<Button Command="{Binding SomeCommand}"
CommandParameters="{Binding SelectedItems, ElementName=MyListBox}" />

WPF: Bind to SelectedItem of row in DataGrid

I'm very new to WPF. I'm trying to bind to a property a row in a DataGrid so that when the row's clicked the property is set. The ItemsSource that's bound to the DataGrid is an ObservableCollection of objects of type Field.
I've tried to bind to the SelectedItem attribute on the DataGrid, but the property is not being called. I'm using almost identical code to bind to the SelectedItem of a ComboBox and this is working fine. Is there a difference that I don't know about?
<ComboBox ItemsSource="{Binding RecordTypes}" SelectedItem="{Binding SelectedRecordType}" ...
<DataGrid ItemsSource="{Binding Fields}" SelectedItem="{Binding SelectedField}" ...
In my ViewModel:
private Field SelectedField
{
get
{
return _selectedField;
}
set
{
_selectedField = value;
}
}
(I will use auto properties later, it's just currently set up like this so that I could break when the property was set).
I'm not sure if it makes a difference, but the DataGrid is composed of 2 DataGridTextColumns and a DataGridTemplateColumn, which contains a checkbox.
Does anyone have any ideas? I'd really appreciate any suggestions.
To confirm, the reason that I want to listen to the click of a row is so that I can have the checkbox be checked whenever a row is clicked. If there's a better solution for this then please let me know.
You need to make it a two-way binding:
SelectedItem="{Binding SelectedField,Mode=TwoWay}"
That propagates changes in the view (user selects an item, SelectedItem changes) back to the viewmodel ("SelectedField" property).
Also, as #KevinDiTraglia pointed out, you need to make sure that the viewmodel property SelectedField is public, not private, otherwise the binding will not be able to access the getter/setter.

How do I bind to one data source but update trigger from another?

I have a TextBox with a OneWay binding to a string property, and I'd like it to update when some other property on my DataContext changes. My DataContext is an ObservableCollection and the TextBox displays statistics about the collection. So I want the statistics to be updated whenever the collection changes, but I don't want to have to raise a dummy "statistics changed" event.
In other words, does XAML (or databinding generally) allow me to specify one binding for the data of a control and another for its update event?
If I understand you correctly, there is a much easier way to achieve what you want:
<ListBox ItemsSource={Binding Items} />
<TextBox Text="{Binding Items/PropertyName}" />
Assuming that your ObservableCollection has a bindable property named PropertyName in it and that your view model (or DataContext) has a property called Items of the type of your ObservableCollection, then the TextBox control will display the PropertyName value of the currently selected item in the collection.
You can find out more about the '/' path syntax from the PropertyPath XAML Syntax page on MSDN.

Combobox DataBinding

I'm having a problem with a combobox. I use databinding to display the content of a list (guinodes). My UINode items in the list implement INotifyPropertyChanged and raise PropertyChanged on name changes. If I change the name of an item the combobox is updated, however combobox.Text remains the old value. Also please note that combobox.SelectedValue.ToString() contains only the type.
Databinding looks like that :
ItemsSource="{Binding ElementName=graphCanvas, Path=guinodes}"
your combobox SelectedValue or SelectedItem should be the selected UINode item, just take it and get the information you want from it. dont know why you use combobox.Text?
use this:
<ComboBox x:Name="SubCategory" ItemsSource="{Binding ElementName=graphCanvas, Path=guinodes}" DisplayMemberPath="SubCategoryName" SelectedValuePath="**SubCategoryID**" SelectedValue="{Binding SubCategoryID,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
Good Luck

Categories

Resources