我必须选择在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>
但是我真的不知道附加属性和附加行为之间的区别,以及在ViewModel中获取SelectedItems的最佳选择是什么。
谢谢。
答案 0 :(得分:1)
在WPF中,基本上有两种不同的方式来实现附加行为。当依赖项属性的值更改时,您可以创建一个附加属性,并对其应用PropertyChangedCallback
,以对其执行一些操作,或者扩展附加属性DependencyObject
。
另一种方法是创建一个从System.Windows.Interactivity.Behavior<T>
派生的类。与创建带有回调的附加属性相比,这通常称为“混合”行为,它提供了封装行为功能的更好方法。 Blend行为也更易于设计,因为它们可以通过Blend中的拖放功能轻松地附加到UI中的可视元素,并且它们还提供了一种简单明了的方法来使用OnAttached
附加和释放事件处理程序和OnDetaching
方法。主要缺点是您不能在样式设置器中应用这些行为。
因此,如果您需要能够将自己的行为附加在Style
中,请使用附加属性。否则,我宁愿使用混合行为。有一个示例,您可以根据需要绑定到on this blog的只读属性。