【问题标题】:WPF Datagrid Double Click Cell MVVM DesignWPF Datagrid 双击单元格 MVVM 设计
【发布时间】:2013-09-03 15:06:44
【问题描述】:

我有一个包含数据网格的 WPF 应用程序。它绑定到我的 List 对象“Orders”,如下所示。

public class OrderBlock
{
  public Settings setting;
  public List<Order> orders;
}
public class Order
{
  public int Amount;
  public string OrderID;
  public string OrderIDDup;
  public string Name;
  public string NameDup;
  public bool DupIDs;
  // and some string, int fields
}

由于我无法控制的原因,可能有多个 OrderID,因此 OrderIDDup 属性。默认情况下,我的数据网格仅显示 OrderID 而不是 OrderIDDup。

我想做的是让用户能够单击单元格 ID 并加载另一个窗口以向他们显示另一个 ID 以及两个名称,并让他们选择应该使用哪个 ID。

我读到 WPF DataGrid 不支持双击单元格的功能。所以我有点迷茫,因为我应该如何开始处理这个问题。我可以看到的另一个问题是,当我尝试(作为有效词)使用 MVVM 设计时,如何将这种事件暴露给我的视图模型?

这也是显示此类信息的最佳方式。

任何帮助都会很棒, 谢谢, M

【问题讨论】:

  • 右键点击怎么样?或使用带有计时器和计数器的普通 clickevent ala if (cell = oldcell &amp;&amp; time &lt; maxtime &amp;&amp; count ==2) dostuff
  • RowDetails 可能是另一种实现方式
  • 我同意@jim Rowdetails 是要走的路。然后,您可以使用下拉菜单、按钮或任何您想要的值来选择值。您使用的是什么 mvvm 框架。 Mvvm-Light 有一个事件命令,您可以使用它来将 UI 相关事件绑定到视图模型函数并保留 MVVM 模式。
  • wpf 数据网格是否有右键单击事件?当您说 RowDetails 时,您的意思是我可以获取用户单击的行并从中检测到他们单击的列?
  • 使用RowDetailsTemplate 会使每一行都像一个扩展器一样,并在单击该行时展开更多信息。您可以将两个Textblocks 放入模板中以保存您的附加信息。在 SO 或谷歌搜索上有很多关于此的信息。

标签: c# wpf xaml mvvm datagrid


【解决方案1】:

您可以双击网格而不是双击单元格

<DataGrid.InputBindings>
    <MouseBinding Gesture="LeftDoubleClick" 
    Command="{Binding Edit}" 
    CommandParameter="{Binding ElementName=UsersDataGrid, Path=SelectedItem}" />
</DataGrid.InputBindings>

在视图模型中

    public ICommand Edit { get; private set; }

 Edit = new RelayCommand(EditUser, x => _isAdmin);



 private static void EditUser(object usr)
    {
        if (!(usr is User))
            return;

        new UserEditorViewModel(usr as User);
    }

【讨论】:

  • 抱歉,我不太擅长 WPF。如果他们双击网格,我如何知道他们点击了哪一行?我了解 ICommand 部分。
  • CommandParameter="{Binding ElementName=UsersDataGrid, Path=SelectedItem}
【解决方案2】:

我们可以通过两种方式做到这一点,

a) 通过使用依赖属性 b) 通过添加 System.Windows.Interactivity.dll。

通常我更喜欢第二种方式。

第 1 步:在您的视图模型类文件中实现 ICommand 接口。

第 2 步:定义您的命令,

public ICommand DoubleClickCommand
{
//Do your code
}

第2步:将上述.dll添加到您相应解决方案的xaml文件中。

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

步骤 3:在 Datagrid 标签内,使用以下代码实现 InvokeCommandAction 类

<i:Interaction.Triggers>
       <i:EventTrigger EventName="MouseDoubleClick">
             <i:InvokeCommandAction Command="DoubleClickCommand"/>
       </i:EventTrigger>
<i:Interaction.Triggers>

就是这样。希望对你有帮助:)

【讨论】:

  • 这会在鼠标双击 DataGrid 的任何区域(例如列标题、行标题、滚动条等)时触发事件
【解决方案3】:
private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs eventArgs)
{
    if (sender == null) return;
    if (eventArgs.ButtonState != MouseButtonState.Pressed) return; //only react on pressed

    var dataGrid = sender as DataGrid;
    if (dataGrid == null || dataGrid.SelectedItems == null) return;

    if (dataGrid.SelectedItems.Count == 1)
    {
        var simplePension = dataGrid.SelectedItem as ISimplePension;
        if (simplePension != null)
        {
            DataFetcherHolder.DataFetcher.SelectPension(simplePension);
            Execute(EditSelectedPensionFunction);
        }
    }
}

【讨论】:

  • 不过,这不是 mvvm。
【解决方案4】:

我用过鼠标双击:

    private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs eventArgs)
    {
        if (sender == null) return;
        if (eventArgs.ButtonState != MouseButtonState.Pressed) return; //only react on pressed

        var dataGrid = sender as DataGrid;
        if (dataGrid == null || dataGrid.SelectedItems == null) return;

        if (dataGrid.SelectedItems.Count == 1)
        {
            var simplePension = dataGrid.SelectedItem as ISimplePension;
            if (simplePension != null)
            {
                DataFetcherHolder.DataFetcher.SelectPension(simplePension);
                Execute(EditSelectedPensionFunction);
            }
        }
    }

当你双击一个数据网格时,该行也被选中了,所以我简单地找到选中的项并使用它。

【讨论】:

  • 这不是 MVVM。
【解决方案5】:

假设

  1. DataGrid 作为 MyGridDataList
  2. 选定行的网格数据为 MyGridData
public Icollection<MyGridData> MyGridTable {get; private set;}
public MyGridData MyData {get; private set;}

public MyClass()
{
    MyGridData = new MyGridData();
    /// assume datas had set
    MyGridTable = new ObservableCollection<MyGridData>();
    MyGridTable.Add(MyGridData); //more then 2 datas
}

推送 MyGridTable 2 或更多 MyGridData 以查找 MyGridData 找到的选定行。 然后,xaml端

<!--abstract... your GridData tag -->
<DataGrid SelectedItem="{Binding MyData}" ItemSource="{Binding MyGridTable}"/>
<!--And put Trigger Code ABOVE Reply-->

Lanch App 并双击DataGrid,然后可以找到Correspond MyData 在 MyGridTable 中选择行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2012-11-22
    • 1970-01-01
    • 2015-10-03
    • 2020-03-09
    相关资源
    最近更新 更多