我正在使用Microsoft.Toolkit.Mvvm nuget 包在 .NET Core 3.1 上構建 WPF 應用程式。
我在系結 Datagrid 的 DataGridTemplateColumn 中的按鈕的 CommandParameter 時遇到問題。
我在我的視圖模型上定義了一個 RelayCommand,使用 IRelayCommand,并定義了一個帶有引數的 CanExecute 方法。然后,我將按鈕系結的 CommandParameter 系結到資料網格行的資料。
在運行時,我看到我的資料網格的每一行都呼叫了 CanExecute 方法,但是引數值始終為空。如果我的 ObservableCollection 中有 5 個專案,我會看到 CanExecute 被呼叫了 5 次,3 個專案...... 3 次。在所有情況下,該值為空。
下面是用于創建 TestModel 型別的 ObservableCollection 的視圖模型的代碼。創建了一個 RelayCommand,CanExecute 的標準被簡化為僅比較資料系結模型的 name 屬性。
我在這里期望的是,對于除名稱為“Test2”的行之外的所有行,系結按鈕都將被啟用。Test2 行中的按鈕將被禁用。
這是我的視圖模型和相關的模型類。
public class MainWindowVM : ObservableObject, IViewModel
{
public MainWindowVM()
{
TestData = new ObservableCollection<TestModel>
{
new TestModel() {Name = "Test1"},
new TestModel() {Name = "Test2"},
new TestModel() {Name = "Test3"}
};
DeleteCommand = new RelayCommand<TestModel>(Delete, CanDelete);
}
public IRelayCommand<TestModel> DeleteCommand { get; }
private void Delete(TestModel model)
{
//do stuff
}
private bool CanDelete(TestModel model)
{
if (model.Name == "Test2")
{
return false;
}
return true;
}
public ObservableCollection<TestModel> TestData
{
get => _testData;
set => SetProperty(ref _testData, value);
}
private ObservableCollection<TestModel> _testData;
}
public class TestModel : ObservableObject
{
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
private string _name;
}
還有我的 Datagrid 的 xaml
<Grid>
<DataGrid ItemsSource="{Binding Path=TestData}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Username"
Binding="{Binding Path=Name}"
MinWidth="180" />
<DataGridTemplateColumn Header="" Width="160">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}" Content="Delete"
Width="100" >
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
我在這里想念什么?我在其他 WPF 應用程式中無數次使用這種方法。這是我第一次使用這個工具包(我之前使用過 MVVMLight),也是第一次在 .NET Core 上構建 WPF。這是 .NET Core 上 WPF 的變化嗎?兩個 MVVM 工具包之間有什么不同嗎?
您可以提供的任何幫助或指導將不勝感激,謝謝。
uj5u.com熱心網友回復:
我在這里想念什么?
CanExecute在設定之前呼叫的事實CommandParameter。
將系結更改為此似乎對我有用:
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Self}}"
另請注意,除非您將CanUserAddRows屬性設定為DataGridto false,否則您CanDelete也將被呼叫,MS.Internal.NamedObject這將導致應用程式崩潰,除非您更改您的型別引數RelayCommand:
public class MainWindowVM : ObservableObject
{
public MainWindowVM()
{
TestData = new ObservableCollection<TestModel>
{
new TestModel() {Name = "Test1"},
new TestModel() {Name = "Test2"},
new TestModel() {Name = "Test3"}
};
DeleteCommand = new RelayCommand<object>(Delete, CanDelete);
}
public IRelayCommand<object> DeleteCommand { get; }
private void Delete(object parameter)
{
if (parameter is TestModel model)
{
//do stuff
}
}
private bool CanDelete(object parameter)
{
if (parameter is TestModel model && model.Name == "Test2")
{
return false;
}
return true;
}
public ObservableCollection<TestModel> TestData
{
get => _testData;
set => SetProperty(ref _testData, value);
}
private ObservableCollection<TestModel> _testData;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/422329.html
標籤:
