【问题标题】:MVVM DataGrid SelectedItem binding doesn’t get updatedMVVM DataGrid SelectedItem 绑定未更新
【发布时间】:2012-07-16 13:03:29
【问题描述】:

我是 .Net 和 C# 的新手,对绑定有点困惑。我有实现 MVVM 并显示 DataGrid 的应用程序。我想要实现的是,当用户按下某个组合键时,当前选定单元格的内容会被复制到下面一行的单元格中。 我尝试将 DataGrid 的 SelectedItem 绑定到 ViewModel 属性,但它永远不会更新。 CommandParameter 也不起作用,项目计数始终为 0。 所以我无法提取用户选择的单元格,也无法读取所选单元格的内容。 有没有人建议如何解决这个问题或实现这个功能? 提前致谢。 代码: xml:

<DataGrid Grid.Row="1" 
          Grid.Column="0" 
          Grid.ColumnSpan="9" 
          AutoGenerateColumns="False" 
          Height="Auto" 
          HorizontalAlignment="Left" 
          Name="dataGrid" 
          VerticalAlignment="Top" 
          Width="{Binding ElementName=grid4,Path=Width}"
          ScrollViewer.CanContentScroll="False" 
          FrozenColumnCount="1" 
          SelectionUnit="Cell" 
          SelectionMode="Extended" 
          CanUserSortColumns = "False" 
          CanUserReorderColumns="False" 
          CanUserResizeRows="False" 
          RowHeight="25" 
          RowBackground="LightGray" 
          AlternatingRowBackground="White"
          ScrollViewer.VerticalScrollBarVisibility="Visible" 
          ScrollViewer.HorizontalScrollBarVisibility="Visible"
          ItemsSource="{Binding Layers, Mode=TwoWay}"  
          SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Selection, Mode=TwoWay}">
    <DataGrid.InputBindings>
        <KeyBinding Gesture="Shift" 
                    Command="{Binding ItemHandler}" 
                    CommandParameter="{Binding ElementName=dataGrid, Path=SelectedItems}">
        </KeyBinding>
    </DataGrid.InputBindings>
</DataGrid>

视图模型:

private float _selection = 0.0f;
    public float Selection
    {
        get
        {
            return _selection;
        }
        set
        {
            if (_selection != value)
            {
                _selection = value;
                NotifyPropertyChanged("Selection");
            }
        }
    }

...

        public DelegateCommand<IList> SelectionChangedCommand = new DelegateCommand<IList>(
        items =>
        {
            if (items == null)
            {
                NumberOfItemsSelected = 0; 
                return;
            }
            NumberOfItemsSelected = items.Count;
        });
    public ICommand ItemHandler
    {
        get
        {
            return SelectionChangedCommand;
        }
    }

【问题讨论】:

  • 图层是浮动元素的集合吗?
  • Layers 是一个包含 Layer 对象的 ObservableCollection。类层实现 INotifyPropertyChanged 并具有浮动字段。 DataGrid 单元格显示一个图层浮动字段。
  • 也许你应该添加你想要实现的目标。我是对的:当用户单击一个单元格时,下一行相同的单元格应该是相同的值?奇怪的要求。当用户单击最后一行中的单元格时会发生什么?
  • “当用户单击一个单元格时,下一行相同的单元格应该是相同的值”是的,这就是要求。 (虽然点击更像是“Ctrl+D”之类的快捷方式)如果单元格在最后一行,则什么也不会发生。

标签: binding mvvm .net-4.0 wpfdatagrid selecteditem


【解决方案1】:

编辑:SelectionUnit=Cell 不适用于 SelectedItem

这是正常的 mvvm 方式:

第一个你想在每一行显示的对象类型

 public class MyObject {}

第二个视图模型,它包含集合和选定的项目

 public class MyViewmodel
 {
    public ObservableCollection<MyObject> MyItems {get;set;}
    public MyObject MySelectedItem {get;set;}

 }

xaml 数据网格

 <DataGrid ItemsSource="{Binding MyItems}" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}"/>

这就是你所拥有的。如果您现在想创建一个“复制”行的命令,您可以创建一个新对象 MyObject 并从您的 MySelectedItem 复制值,然后将新的 MyObject 添加到您的集合中。

但也许我没有正确回答您的问题。

【讨论】:

  • 感谢您的回复。问题是 MySelectedItem 始终为 null,并且从未调用过 MySelectedItem 的 set 方法。
  • 所以 SelectedItem 总是行?如何仅从选定的单元格中获取内容?
  • 问题是选择的属性/单元格是正确的。我会说这是一个新问题的主题,只需关闭它并打开一个新问题。我必须搜索一下,这如何与 mvvm 一起使用。也许已经有一种行为了:)
  • 好的,我在这里打开了新问题:stackoverflow.com/questions/11518453/…
【解决方案2】:

我认为你可以添加一个依赖属性。这是属性答案:

public class UIElementMouseRightButtonDownCommandBehavior : CommandBehaviorBase<UIElement>
{
    public UIElementMouseRightButtonDownCommandBehavior(UIElement obj)
        : base(obj)
    {
        if (obj == null) throw new System.ArgumentNullException("obj");
        obj.MouseRightButtonDown += OnMouseRightButtonDown;
    }

    private void OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        ExecuteCommand();
    }       
}

还有一个班级:

 public class MouseRightButtonDown
{
    private static readonly DependencyProperty MouseRightButtonDownCommandBehaviorProperty = DependencyProperty.RegisterAttached(
        "MouseRightButtonDownCommandBehavior",
        typeof(UIElementMouseRightButtonDownCommandBehavior),
        typeof(MouseRightButtonDown),
        null);

    public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached(
        "Command",
        typeof(ICommand),
        typeof(MouseRightButtonDown),
        new PropertyMetadata(OnSetCommandCallback));

    public static void SetCommand(UIElement element, ICommand command)
    {
        element.SetValue(CommandProperty, command);
    }

    public static ICommand GetCommand(UIElement element)
    {
        return element.GetValue(CommandProperty) as ICommand;
    }

    private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        UIElement element = dependencyObject as UIElement;
        if (element != null)
        {
            UIElementMouseRightButtonDownCommandBehavior behavior = GetOrCreateBehavior(element);
            behavior.Command = e.NewValue as ICommand;
        }
    }

    private static UIElementMouseRightButtonDownCommandBehavior GetOrCreateBehavior(UIElement element)
    {
        UIElementMouseRightButtonDownCommandBehavior behavior = element.GetValue(MouseRightButtonDownCommandBehaviorProperty) as UIElementMouseRightButtonDownCommandBehavior;
        if (behavior == null)
        {
            behavior = new UIElementMouseRightButtonDownCommandBehavior(element);
            element.SetValue(MouseRightButtonDownCommandBehaviorProperty, behavior);
        }
        return behavior;
    }
}

然后在您的视图模型文件中:

public ICommand SelectNameCommand
    {
        get { return new Command(P => SelectName()); }
    }

我认为您的 XAML 是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 2018-12-20
    • 2012-05-26
    • 2014-08-26
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多