Binding.Converter к Visible DataGridTextColumn
Необходимо прибиндить конвертор к DataGridTextColumn.
DataGrid.ItemsSource прикреплен к:
private ObservableCollection<AppealModel> _dataTable;
public ObservableCollection<AppealModel> DataTable
{
get => _dataTable;
set => Set(ref _dataTable, value);
}
(в прикрепленно ViewModel соответственно)
XAML:
xmlns:converter="clr-namespace:appSend.Controllers.Converter"
<Page.Resources>
<converter:TableColumnVisibilityConverter x:Key="VisibilityConverter"/>
</Page.Resources>
<DataGrid ItemsSource="{Binding DataTable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn Header="Номер дела" Binding="{Binding Path=CaseNumber}"
Visibility="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType=DataGrid}, Converter={StaticResource VisibilityConverter}, ConverterParameter=CaseNumber}"/>
<DataGridTextColumn Header="Короткое имя" Binding="{Binding Path=ShortName}"
Visibility="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType=DataGrid}, Converter={StaticResource VisibilityConverter}, ConverterParameter=ShortName}"/>
</DataGrid.Columns>
</DataGrid>
описал без ненужных подробностей, все подключено как положено, ошибок нет, проект компилируется.
Converter:
public class TableColumnVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not IEnumerable || parameter is not string propertyName || string.IsNullOrWhiteSpace(propertyName))
return Visibility.Hidden;
Type type = null;
PropertyInfo pi = null;
foreach (object item in (IEnumerable)value)
{
if (type is null)
{
type = item.GetType();
if (type.IsValueType)
return Visibility.Visible;
}
if (pi is null)
pi = type.GetProperty(propertyName);
if (pi.GetValue(item) is not null)
return Visibility.Visible;
}
return Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
Ответы (1 шт):
Проблема в том, что DataGridTextColumn не является частью визуального дерева и привязки на ней в принципе не работают. Единственное, что с этими привязками работает - это ресурсы StaticResource.
Через конвертер мне победить не удалось. Но если задача сводится к управлению видимостью колонок, то можно сделать это через вьюмодель для них.
Использую код из прошлого вопроса и делаю вот такую вьюмодель
public class AppealColumnViewModel : NotifyPropertyChanged
{
private bool caseNumber = true;
private bool shortName = true;
private bool file = true;
private bool text = true;
private bool courtRegion = true;
private bool courtNumber = true;
private bool fileExist = true;
private bool done = true;
private bool enforcementProceedingsNumber = true;
private bool enforcementProceedingsId = true;
private bool osp = true;
private bool copyrightHolderName = true;
private bool clientName = true;
private bool courtName = true;
public bool CaseNumber { get => caseNumber; set => Set(ref caseNumber, value); }
public bool ShortName { get => shortName; set => Set(ref shortName, value); }
public bool File { get => file; set => Set(ref file, value); }
public bool Text { get => text; set => Set(ref text, value); }
public bool CourtRegion { get => courtRegion; set => Set(ref courtRegion, value); }
public bool CourtNumber { get => courtNumber; set => Set(ref courtNumber, value); }
public bool FileExist { get => fileExist; set => Set(ref fileExist, value); }
public bool Done { get => done; set => Set(ref done, value); }
public bool EnforcementProceedingsNumber { get => enforcementProceedingsNumber; set => Set(ref enforcementProceedingsNumber, value); }
public bool EnforcementProceedingsId { get => enforcementProceedingsId; set => Set(ref enforcementProceedingsId, value); }
public bool Osp { get => osp; set => Set(ref osp, value); }
public bool CopyrightHolderName { get => copyrightHolderName; set => Set(ref copyrightHolderName, value); }
public bool ClientName { get => clientName; set => Set(ref clientName, value); }
public bool CourtName { get => courtName; set => Set(ref courtName, value); }
}
В основную вьюмодель заношу свойство
public AppealColumnViewModel ColumnsState { get; } = new();
Далее создаю класс для ресурса-прокси
public class BindingProxy : Freezable
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(BindingProxy));
protected override Freezable CreateInstanceCore() => new BindingProxy();
public object Value
{
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
}
Далее вношу это в ресурсы DataGrid
<DataGrid.Resources>
<local:BindingProxy x:Key="ColumnsState" Value="{Binding ColumnsState}"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</DataGrid.Resources>
И делаю вот такую привязку
<DataGridTextColumn Header="Номер дела" Binding="{Binding CaseNumber}"
Visibility="{Binding Value.CaseNumber, Source={StaticResource ColumnsState}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
Теперь можно делать вкл и выкл колонки просто задав
ColumnsState.CaseNumber = false;