如何使用MVVM在WPF中设置GridView的SelectedItems属性

时间:2011-09-23 18:19:21

标签: wpf data-binding listview gridview selecteditem

我的wpf应用程序中有一个gridview,其中xaml看起来像这样:

   <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>

以下是我用于获取所选项目的附加行为:

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);
        }

这适用于在用户单击按钮或其他内容时在viewmodel中获取所选项目。我的问题是,当屏幕加载时,我需要突出显示之前选择的项目。我没有成功尝试在VM的构造函数中设置'SelectedPartTypes'属性,假设双向绑定将处理它。是否有一种简单的方法可以显示控件加载时选择了哪些项目?

1 个答案:

答案 0 :(得分:2)

无法绑定ListBoxItem样式中的IsSelected属性吗?

<Style TargetType="ListBoxItem">
    <Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>

如果您的数据对象没有跟踪选择的属性,如果当前对象位于SelectedPartTypes

内,您可能需要使用转换器返回true