如何将命令绑定到ListView';s ItemSelectionChanged事件

本文关键字:ItemSelectionChanged 事件 ListView 命令 绑定 | 更新日期: 2023-09-27 17:57:31

是否可以将命令绑定到ListView的ItemSelectionChanged?怎样如果不可能,当列表视图的选择发生更改时,是否有其他方法可以调用命令?

如何将命令绑定到ListView';s ItemSelectionChanged事件

是--MVVM轻框架支持将命令数据绑定到路由事件。看见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 posted一样使用一种EventToCommand行为,就像mvvm-light一样。

另一种方法是创建一个附加行为,以绑定到视图模型中的selecteditem。您必须熟练使用以下代码来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),
            typeof(DatagridService),
            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
}
相关文章:
  • 没有找到相关文章