【问题标题】:WPF MVVM - Get access to DependencyProperty of DataGrid in View from ViewModelWPF MVVM - 从 ViewModel 访问视图中 DataGrid 的 DependencyProperty
【发布时间】:2017-11-24 01:21:17
【问题描述】:

在我的视图中,我有一个DataGrid,它存储了 2 种降序类型的对象。每行都有一个带有命令的按钮连接到 ViewModel。在 ViewModel 中,我需要找出选择了哪种类型的对象。

问题是从 ViewModel 中的Execute 命令方法访问DataGridSelectedItem 属性的最佳且简单的方法是什么?

到目前为止,我是这样做的:

var window = Application.Current.Windows.OfType<Window>()
    .SingleOrDefault(x => x.IsActive);

var dataGrid = (DataGrid) window.FindName("MyGridName");
...

更新 - Xaml:

<DataGrid Name="MyGridName" ItemsSource="{Binding Elements}"
          AutoGenerateColumns="False" CanUserAddRows="False"
          CanUserDeleteRows="False" IsReadOnly="True">
  <DataGrid.Columns>
    <DataGridTemplateColumn Width="auto">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <Button Name="OptionsBtn" Margin="5" Width="auto"
                  Height="30" Content="Options"
                  Command="{Binding ElementName=ElementsViewWindow,
                      Path=DataContext.ShowOptionsMenuCommand}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

【问题讨论】:

  • 将您的 Grid 的 SelectedItem 绑定到某个 VM 属性或使用 CommandParameters 并停止您正在尝试做的任何事情...
  • 显示 Xaml 中的命令以及如何绑定它。我很高兴向您展示如何采用这种命令参数方法!
  • &lt;Button Name="OptionsBtn" Margin="5" Width="auto" Height="30" Content="Options" Command="{Binding ElementName=ElementsViewWindow, Path=DataContext.ShowOptionsMenuCommand}" CommandParameter="{Bidning .}"/&gt;

标签: c# wpf mvvm viewmodel dependency-properties


【解决方案1】:

如果您采用正确的 MVVM 方法,这很容易做到。您只需要定义将绑定到DataGridItemsSource 的实体的项目集合和将绑定到DataGridSelectedItem 的属性。然后在您的命令中,您只需引用模型的 selected item 属性即可访问 DataGrid 中的选定项目。

这是一个使用 MVVM Light 的示例实现。首先,您定义一个可观察的实体集合:

public const string ItemsCollectionPropertyName = "ItemsCollection";
private ObservableCollection<DataItem> _itemsCollection = null;
public ObservableCollection<DataItem> ItemsCollection
{
    get
    {
        return _itemsCollection;
    }
    set
    {
        if (_itemsCollection == value)
        {
            return;
        }

        _itemsCollection = value;
        RaisePropertyChanged(ItemsCollectionPropertyName);
    }
}

然后定义一个属性来保存所选项目:

public const string SelectedItemPropertyName = "SelectedItem";
private DataItem _selectedItem = null;
public DataItem SelectedItem
{
    get
    {
        return _selectedItem;
    }
    set
    {
        if (_selectedItem == value)
        {
            return;
        }

        _selectedItem = value;
        RaisePropertyChanged(SelectedItemPropertyName);
    }
}

然后定义一个命令来处理业务逻辑:

private ICommand _doWhateverCommand;
public ICommand DoWhateverCommand
{
    get
    {
        if (_doWhateverCommand == null)
        {
            _doWhateverCommand = new RelayCommand(
                () => { /* do your stuff with SelectedItem here */  },
                () => { return SelectedItem != null; }
            );
        }
        return _doWhateverCommand;
    }
}

最后你创建视图元素并将它们绑定到ViewModel:

<DataGrid ItemsSource="{Binding ItemsCollection}" SelectedItem="{Binding SelectedItem}" AutoGenerateColumns="True" />
<Button Content="Do stuff" Command="{Binding DoWhateverCommand}" />

【讨论】:

    【解决方案2】:

    问题是从 ViewModel 中的 Execute 命令函数访问 DataGrid 的 SelectedItem 属性的最佳且简单的方法是什么?

    只需在定义了ShowOptionsMenuCommand 属性的视图模型类中添加一个属性,并将DataGridSelectedItem 属性绑定到这个:

    <DataGrid Name="MyGridName" ItemsSource="{Binding Elements}" SelectedItem="{Binding SelectedElement}" ... >
    

    然后您可以直接从Execute 方法访问源属性(SelectedElement 或您选择的任何名称)。

    另一种选择是将项目作为CommandParameter 传递给命令:

    <Button Name="OptionsBtn" ... Content="Options" 
            Command="{Binding ElementName=ElementsViewWindow, Path=DataContext.ShowOptionsMenuCommand}"
            CommandParameter="{Binding}" />
    

    【讨论】:

      猜你喜欢
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      相关资源
      最近更新 更多