如何解决如何将命令绑定到ListView的ItemSelectionChanged事件?
| 是否可以将命令绑定到ListView的ItemSelectionChanged?怎么样?如果不可能,是否有另一种方法可以在列表视图的选择更改时调用命令?解决方法
是的-MVVM-light框架支持将命令数据绑定到路由事件。参见http://blog.galasoft.ch/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2-eventtocommand-behavior.aspx
<Rectangle Fill=\"White\"
Stroke=\"Black\"
Width=\"200\"
Height=\"100\">
<i:Interaction.Triggers>
<i:EventTrigger EventName=\"MouseEnter\">
<cmd:EventToCommand Command=\"{Binding TestCommand,Mode=OneWay}\"
CommandParameter=\"{Binding Text,ElementName=MyTextBox,Mode=OneWay}\"
MustToggleIsEnabledValue=\"True\" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
,首先,我在我的项目中使用一条命令,其中selectedItems作为参数传递。这种方法的缺点是用户必须轻按命令按钮才能开始操作,但这在大多数情况下可以满足我的要求。
实现您想要的方式的方法是发布erash-使用诸如mvvm-light的EventToCommand行为。
另一种方法是创建附加行为以绑定到视图模型中的selecteditems。您必须将以下代码用于ListView或创建更通用的方法:)
<DataGrid AttachedProperties:DatagridService.SelectedItemsSource=\"{Binding SelectedItems,Mode=OneWay}\" />
ViewModel:
public ObservableCollection<object> SelectedItems//init collection just ONCE!
{
get
{
if (this.selectedItems == null)
{
this.selectedItems = new ObservableCollection<object>();
this.selectedItems.CollectionChanged +=
new System.Collections.Specialized.NotifyCollectionChangedEventHandler(SelectedItemsCollectionChanged);
}
return this.selectedItems;
}
}
private void SelectedItemsCollectionChanged(object sender,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//this is called when ever the selecteditems changed
}
附带行为:
public static class DatagridService
{
#region SelectedItemSource
#region Attached Property Declaration
/// <summary>
/// Identifies the ListBoxExtension.SelectedItemsSource attached property.
/// </summary>
public static readonly DependencyProperty SelectedItemsSourceProperty =
DependencyProperty.RegisterAttached(
\"SelectedItemsSource\",typeof(IList),typeof(DatagridService),new PropertyMetadata(
null,new PropertyChangedCallback(OnSelectedItemsSourceChanged)));
#endregion
#region Attached Property Accessors
/// <summary>
/// Gets the IList that contains the values that should be selected.
/// </summary>
/// <param name=\"element\">The ListBox to check.</param>
public static IList GetSelectedItemsSource(DependencyObject element)
{
if (element == null)
throw new ArgumentNullException(\"element\");
return (IList)element.GetValue(SelectedItemsSourceProperty);
}
/// <summary>
/// Sets the IList that contains the values that should be selected.
/// </summary>
/// <param name=\"element\">The ListBox being set.</param>
/// <param name=\"value\">The value of the property.</param>
public static void SetSelectedItemsSource(DependencyObject element,IList value)
{
if (element == null)
throw new ArgumentNullException(\"element\");
element.SetValue(SelectedItemsSourceProperty,value);
}
#endregion
#region IsResynchingProperty
// Used to set a flag on the ListBox to avoid reentry of SelectionChanged due to
// a full syncronisation pass
private static readonly DependencyPropertyKey IsResynchingPropertyKey =
DependencyProperty.RegisterAttachedReadOnly(
\"IsResynching\",typeof(bool),new PropertyMetadata(false));
#endregion
#region Private Static Methods
private static void OnSelectedItemsSourceChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
DataGrid grd = d as DataGrid;
if (grd == null)
throw new InvalidOperationException(\"The DataGridExtension.SelectedItemsSource attached \" +
\"property can only be applied to DataGrid controls.\");
grd.SelectionChanged -= new SelectionChangedEventHandler(OnDataGridSelectionChanged);
if (e.NewValue != null)
{
ListenForChanges(grd);
}
BindingExpression bexp = grd.GetBindingExpression(SelectedItemsSourceProperty);
if (bexp != null)
bexp.UpdateSource();
}
private static void ListenForChanges(DataGrid grd)
{
// Wait until the element is initialised
if (!grd.IsInitialized)
{
EventHandler callback = null;
callback = delegate
{
grd.Initialized -= callback;
ListenForChanges(grd);
};
grd.Initialized += callback;
return;
}
grd.SelectionChanged += new SelectionChangedEventHandler(OnDataGridSelectionChanged);
ResynchList(grd);
}
private static void OnDataGridSelectionChanged(object sender,SelectionChangedEventArgs e)
{
DataGrid grd = sender as DataGrid;
if (grd != null)
{
bool isResynching = (bool)grd.GetValue(IsResynchingPropertyKey.DependencyProperty);
if (isResynching)
return;
IList list = GetSelectedItemsSource(grd);
if (list != null)
{
foreach (object obj in e.RemovedItems)
{
if (list.Contains(obj))
list.Remove(obj);
}
foreach (object obj in e.AddedItems)
{
if (!list.Contains(obj))
list.Add(obj);
}
}
}
}
private static void ResynchList(DataGrid grd)
{
if (grd != null)
{
grd.SetValue(IsResynchingPropertyKey,true);
IList list = GetSelectedItemsSource(grd);
if (grd.SelectionMode == DataGridSelectionMode.Single)
{
grd.SelectedItem = null;
if (list != null)
{
if (list.Count > 1)
{
// There is more than one item selected,but the listbox is in Single selection mode
throw new InvalidOperationException(\"DataGrid is in Single selection mode,but was given more than one selected value.\");
}
if (list.Count == 1)
grd.SelectedItem = list[0];
}
}
else
{
grd.SelectedItems.Clear();
if (list != null)
{
foreach (object obj in grd.Items)
if (list.Contains(obj))
grd.SelectedItems.Add(obj);
}
}
grd.SetValue(IsResynchingPropertyKey,false);
}
}
#endregion
#endregion
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。