代码之家  ›  专栏  ›  技术社区  ›  Álvaro García

AttachedProperty vs behavior可在ViewModel中获取SelectedItems

  •  0
  • Álvaro García  · 技术社区  · 7 年前

    我必须选择选项才能在ViewModel中获取SelectedItems。

    像这样的附加属性:

    public class ListBoxSelectedItemsAttachedProperty
        {
            #region SelectedItems
            ///
            /// SelectedItems Attached Dependency Property
            ///
            public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.RegisterAttached("SelectedItems", typeof(IList),
            typeof(ListBoxSelectedItemsAttachedProperty),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            new PropertyChangedCallback(OnSelectedItemsChanged)));
    
            public static IList GetSelectedItems(DependencyObject d)
            {
                return (IList)d.GetValue(SelectedItemsProperty);
            }
    
            public static void SetSelectedItems(DependencyObject d, IList value)
            {
                d.SetValue(SelectedItemsProperty, value);
            }
    
            private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                ListBox miLb = (ListBox)d;
                miLb.SelectionChanged += listBox_SelectionChanged;
            }
    
            private static void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                ListBox miLg = (ListBox)sender;
                //Get list box's selected items.
                IEnumerable miDgSelectedItems = miLg.SelectedItems;
                //Get list from model
                IList ModelSelectedItems = GetSelectedItems(miLg);
    
                //Update the model
                ModelSelectedItems.Clear();
    
                if (miLg.SelectedItems != null)
                {
                    foreach (var item in miLg.SelectedItems)
                        ModelSelectedItems.Add(item);
                }
                SetSelectedItems(miLg, ModelSelectedItems);
            }
            #endregion
        }
    

    在axml中,它以这种方式使用,例如在列表框中:

    Behaviors:ListBoxSelectedItemsAttachedProperty.SelectedItems="{Binding MyPropertyInViewModel}"
    

    public class SelectedItemsBehavior : Behavior<MultiSelector>
        {
            protected override void OnAttached()
            {
                AssociatedObject.SelectionChanged += AssociatedObjectSelectionChanged;
            }
            protected override void OnDetaching()
            {
                AssociatedObject.SelectionChanged -= AssociatedObjectSelectionChanged;
            }
    
            void AssociatedObjectSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                List<object> selectedItemList = AssociatedObject.SelectedItems.Cast<object>().ToList();
                ObservableCollection<object> selectedItems = new ObservableCollection<object>(selectedItemList);
                SelectedItems = selectedItems;
            }
            public ObservableCollection<object> SelectedItems
            {
                get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
                set { SetValue(SelectedItemsProperty, value); }
            }
            public static readonly DependencyProperty SelectedItemsProperty =
                DependencyProperty.Register("SelectedItems"
                    , typeof(ObservableCollection<object>)
                    , typeof(SelectedItemsBehavior)
                    ,
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        }
    

    在axml中,以这种方式使用,例如在DataGrid中:

    <i:Interaction.Behaviors>
        <Behaviors:SelectedItemsBehavior SelectedItems="{Binding MyPropertyInViewModel}" />
    </i:Interaction.Behaviors>
    

    谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   mm8    7 年前

    在WPF中实现附加行为基本上有两种不同的方法。您可以创建附加属性并应用 PropertyChangedCallback 对其执行某些操作或扩展 DependencyObject 当dependency属性的值更改时,将附加到该属性。

    另一种方法是创建一个从 System.Windows.Interactivity.Behavior<T> . 这通常被称为“混合”行为,与使用回调创建附加属性相比,它提供了更好的封装行为功能的方法。混合行为也更易于设计,因为它们可以通过混合中的拖放功能轻松地附加到UI中的可视元素,并且它们还提供了一种使用 OnAttached OnDetaching 方法。主要缺点是不能在样式设置器中应用此类行为。

    Style ,使用附加属性。否则,我宁愿使用混合行为。下面是一个如何绑定到只读属性的示例 on this blog 如果你感兴趣的话。