WPF MVVM - 从 ViewModel 获取对 View 中 DataGrid 的 DependencyProperty 的访问权限
WPF MVVM - Get access to DependencyProperty of DataGrid in View from ViewModel
在我的视图中,我有一个 DataGrid
存储 2 种递减类型的对象。每行都有一个 Button 和一个连接到 ViewModel 的 Command。在 ViewModel 中,我需要找出选择了哪种类型的对象。
问题是从 ViewModel 中的 Execute
命令方法访问 DataGrid
的 SelectedItem
属性 的最佳和简单方法是什么?
到目前为止我是这样做的:
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>
如果您采用正确的 MVVM 方法,这很容易做到。您所需要的只是定义您实体的项目集合,这些实体将绑定到您的 DataGrid
的 ItemsSource
和一个 属性 将绑定到您的 [=] 的 SelectedItem
15=]。然后在您的命令中,您只需引用模型的所选项目 属性 即可访问 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}" />
The question is what is the best and simple way of accessing SelectedItem property of DataGrid from Execute command function in a ViewModel?
只需在定义ShowOptionsMenuCommand
属性的视图模型class中添加一个属性并绑定SelectedItem
属性 DataGrid
到这个:
<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}" />
在我的视图中,我有一个 DataGrid
存储 2 种递减类型的对象。每行都有一个 Button 和一个连接到 ViewModel 的 Command。在 ViewModel 中,我需要找出选择了哪种类型的对象。
问题是从 ViewModel 中的 Execute
命令方法访问 DataGrid
的 SelectedItem
属性 的最佳和简单方法是什么?
到目前为止我是这样做的:
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>
如果您采用正确的 MVVM 方法,这很容易做到。您所需要的只是定义您实体的项目集合,这些实体将绑定到您的 DataGrid
的 ItemsSource
和一个 属性 将绑定到您的 [=] 的 SelectedItem
15=]。然后在您的命令中,您只需引用模型的所选项目 属性 即可访问 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}" />
The question is what is the best and simple way of accessing SelectedItem property of DataGrid from Execute command function in a ViewModel?
只需在定义ShowOptionsMenuCommand
属性的视图模型class中添加一个属性并绑定SelectedItem
属性 DataGrid
到这个:
<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}" />