У меня есть DataGrid, и я хочу переключить видимость отдельных DataGridTextColumns с помощью команд, отправленных из ContextMenu. Мне нужен какой-то способ связать конкретный DataGridTextColumn или его параметр Visibility с командой ContextMenu MenuItem. Я могу установить отдельные переменные видимости в моем ViewModel и переключать их с помощью отдельных команд, по одной на DataGridTextColumn, который работает просто отлично, но у меня много много DataGridTextColumns и это выглядит как очень повторяющийся, грязный и, вероятно, неправильный способ решения проблемы .
Пример .xaml:
<FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
<DataGrid ItemsSource="{Binding Shots}" SelectedItem="{Binding SelectedShot, Mode=TwoWay}" AutoGenerateColumns="False" HorizontalScrollBarVisibility="Auto" IsReadOnly="True" AreRowDetailsFrozen="True" HeadersVisibility="All" >
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding DataContext.ShotNumberColumnVisibility, Source={x:Reference dummyElement}}" Binding="{Binding Path=ShotNumber}" Header="Shot #" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Toggle Visibility">
<MenuItem Header="Shot Count" Command="{Binding ToggleVisibilityCommand}" />
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid >
В настоящее время мой View .xaml выглядит, как в примере выше, но с большим количеством столбцов и соответствующим ContextIenu MenuItem для каждого. В моей ViewModel я могу контролировать видимость, изменяя ShotNumberVisibility.
public MyViewModel()
{
ToggleVisibilityCommand = new RelayCommand(ToggleVisibility);
}
public Visibility ShotNumberColumnVisibility { get; set; } = Visibility.Visible;
public void ToggleVisibility(object obj)
{
ShotNumberColumnVisibility = ShotNumberColumnVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
RaisePropertyChanged("ShotNumberColumnVisibility");
}
Я НЕ хочу устанавливать это для каждого отдельного DataGridTextColumn. Как правильно передать любой DataGridTextColumn моему ViewModel, чтобы его видимость можно было переключить с помощью обобщенного c метода?
Из того, что я видел, звучит так, будто мне нужно иметь возможность использовать CommandParameter для отправки любого DataGridTextColumn в мою функцию ToggleVisibility. Это та часть, которую я не могу понять. Я думаю что-то вроде следующего в моем .xaml, но у меня еще не получилось.
CommandParameter="{Binding ElementName=InclinationColumn, Path=Visibility}"
На случай, если все еще неясно, вот какой-то псевдокод для команды, которую я хотел бы иметь, и как бы я хотел его использовать.
<DataGridTextColumn Name="demoColumn" Visibility="{Binding demoColumnVisibility}" />
<MenuItem Header="Toggle Demo Column Visibility" CommandParameter="{Binding demoColumn.Visibility}" Command="{Binding ToggleVisibility}" />
public void ToggleVisibility(object obj)
{
obj.Visibility = !obj.Visibility
//OR MAYBE
//Pass in the name "demoColumn" and use that select which bool to flip. In this case demoColumnVisibility
}
Вот как выглядит мой класс RelayCommand: ICommand ...
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if(execute == null)
{
throw new NullReferenceException("execute");
}
_execute = execute;
_canExecute = canExecute;
}
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
}
Надеюсь, этого достаточно, эта проблема убивает меня часами, и я чувствую, что мне чего-то не хватает, c. Любая помощь очень ценится.