How to set SelectedItems property of GridView in WPF using MVVM
I've got a gridview in my wpf application, the xaml of which looks like this:
<ListView SelectionMode="Extended" ItemsSource="{Binding AllPartTypes}"
local:DataGridService.SelectedItems="{Binding Path=SelectedPartTypes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
some columns...
</GridView>
</ListView.View>
</ListView>
Here is the attached behavior I'm using to get the selected items:
public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached(
"SelectedItems",
typeof(IList),
typeof(DataGridService),
new UIPropertyMetadata(new List<object>() as IList, OnSelectedItemsChanged));
static SelectionChangedEventHandler GetSelectionChangedHandler(DependencyObject obj)
{
return (SelectionChangedEventHandler)obj.GetValue(SelectionChangedHandlerProperty);
}
static void SetSelectionChangedHandler(DependencyObject obj, SelectionChangedEventHandler value)
{
obj.SetValue(SelectionChangedHandlerProperty, value);
}
static readonly DependencyProperty SelectionChangedHandlerProperty =
DependencyProperty.RegisterAttached("SelectionChangedHandler", typeof(SelectionChangedEventHandler),
typeof(DataGridService), new UIPropertyMetadata(null));
//d is MultiSelector (d as ListBox not supported)
static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
if (GetSelectionChangedHandler(d) != null)
return;
if (d is MultiSelector)//DataGrid
{
MultiSelector multiselector = d as MultiSelector;
SelectionChangedEventHandler selectionchanged = null;
foreach (var selected in (d as DataGrid).SelectedItems) // GetSelectedItems(d) as IList)
multiselector.SelectedItems.Add(selected);
selectionchanged = (sender, e) =>
{
SetSelectedItems(d, multiselector.SelectedItems);
};
SetSelectionChangedHandler(d, selectionchanged);
multiselector.SelectionChanged += GetSelectionChangedHandler(d);
}
else if (d is ListBox)
{
开发者_运维知识库 ListBox listbox = d as ListBox;
SelectionChangedEventHandler selectionchanged = null;
selectionchanged = (sender, e) =>
{
SetSelectedItems(d, listbox.SelectedItems);
};
SetSelectionChangedHandler(d, selectionchanged);
listbox.SelectionChanged += GetSelectionChangedHandler(d);
}
}
public static IList GetSelectedItems(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemsProperty, value);
}
This works fine for getting the selected items in the viewmodel when the user clicks a button or something. My problem is that, when the screen loads, I need to highlight the items which were previously selected. I unsuccessfully tried setting the 'SelectedPartTypes' property in the constructor of the VM, assuming that the two-way binding would take care of it. Is there an easy way to show which items are selected when the control loads?
Can't you bind the IsSelected
property in the ListBoxItem Style?
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
If your data objects don't have a property to track selection, you may need to use a converter to return true if the current object is within SelectedPartTypes
精彩评论