CanExecute 메서드로 작업 명령 속성을 가져 오는 데 문제가 있습니다. DataGrid 내부에있는 버튼에 명령을 바인딩했습니다. CommandParameter를 DataGrid의 행에 대한 레코드 일 수있는 버튼의 DataContext에 바인딩했습니다.DataContext가 변경 될 때 WPF 명령 CanExecute가 다시 평가되지 않음
CommandParameter 바인딩이 변경 될 때 CanExecute 메서드를 다시 평가해야합니다.이 경우 행의 DataContext 속성이 설정됩니다. 그러나 행 데이터에 대해 CanExecute 메서드를 평가하는 대신 행이 DataContext를 가져 오기 전에 CanExecute 메서드가 평가되고 DataContext가 업데이트 된 후에 다시 계산되지 않는 것처럼 보입니다.
각 행의 DataContext에 대해 내 명령의 CanExecute 메서드를 평가하는 방법을 알려주시겠습니까?
문제점을 설명하기 위해 샘플 응용 프로그램을 만들었습니다. 여기에 코드입니다 :
<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>
MainWindow.xaml의 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의 코드 숨김
당신은로드하는 경우 예제 코드에서는 모든 행 아웃에서 CanEx ecute 메서드는 원하는 행 특정 데이터 대신 매개 변수로 null을받습니다. 이 샘플이 제대로 작동하면 처음에는 모든 버튼이 활성화되며 종료 시간 열의 값을 설정 한 후에 만 비활성화됩니다.
Perfect. 고맙습니다! –