我無法讓我的命令的CanExecute方法工作屬性。我已經綁定了一個命令到一個DataGrid中的按鈕。我已經將CommandParameter綁定到按鈕的DataContext上,這恰好是DataGrid中的一行記錄。WPF命令CanExecute在DataContext更改時未被重新評估
我希望發生的是在CommandParameter綁定更改時重新評估CanExecute方法,在此情況下,該方法將設置行的DataContext屬性。但不是針對行數據評估CanExecute方法,而是在行獲取其DataContext之前對CanExecute方法進行評估,並且在更新DataContext之後不會重新評估該方法。
你能告訴我如何讓我的命令的CanExecute方法根據每行的DataContext進行評估嗎?
我創建了一個示例應用程序來演示我的問題。下面的代碼:
代碼隱藏在MainWindow.xaml
public partial class MainWindow : Window
{
public ObservableCollection<LogRecord> Records { get; private set; }
public ICommand SignOutCommand { get; private set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
Records = new ObservableCollection<LogRecord>();
SignOutCommand = new SignOutCommand();
CreateDemoData();
}
private void CreateDemoData()
{
for (int i = 0; i < 5; i++)
{
Records.Add(new LogRecord());
}
}
}
public class LogRecord : INotifyPropertyChanged
{
private DateTime _EntryTime;
public DateTime EntryTime
{
get { return _EntryTime; }
set
{
if (_EntryTime == value) return;
_EntryTime = value;
RaisePropertyChanged("EntryTime");
}
}
private DateTime? _ExitTime;
public DateTime? ExitTime
{
get { return _ExitTime; }
set
{
if (_ExitTime == value) return;
_ExitTime = value;
RaisePropertyChanged("ExitTime");
}
}
public LogRecord()
{
EntryTime = DateTime.Now;
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public class SignOutCommand : ICommand
{
#region Implementation of ICommand
public void Execute(object parameter)
{
var record = parameter as LogRecord;
if (record == null) return;
record.ExitTime = DateTime.Now;
}
public bool CanExecute(object parameter)
{
var record = parameter as LogRecord;
return record != null && !record.ExitTime.HasValue;
}
public event EventHandler CanExecuteChanged;
#endregion
}
的XAML爲MainWindow.xaml
<Window x:Class="Command_Spike.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<DataGrid ItemsSource="{Binding Path=Records}" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Entry Time" Binding="{Binding Path=EntryTime}" />
<DataGridTextColumn Header="Exit Time" Binding="{Binding Path=ExitTime}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window},
Path=DataContext.SignOutCommand}"
CommandParameter="{Binding}"
Content="Sign Out" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
如果加載了示例代碼中,您可以看到所有註銷按鈕都被禁用,因爲在每一行CanEx中都是如此ecute方法接收空值作爲參數,而不是我想要的行特定數據。如果此示例工作正常,則最初將啓用所有按鈕,並且只有在設置了退出時間列中的值後纔會禁用。
完美。謝謝! –