C# WPF привязать List к чекбоксам и DataGrid Header'ам

161
26 июля 2019, 20:20

есть список

List<string> chlist2 = new List<string>() { "Ф", "И", "О",
            "Дата рожд.", "Адрес" и т.д.};  

В окне ListView который должен заполняться чекбоксами из списка
и DataGrid, заголовки столбцов тоже берутся из списка.

public class chListItem {
    public bool isCheck { get; set; }
    public string ttl{get;set;}
}
List<chListItem> chList = new List<chListItem>();
foreach (string s in chlist2)
{
    chList.Add(new chListItem { isCheck = true, ttl = s });
    DataGridTextColumn textColumn = new DataGridTextColumn();
    textColumn.Header = s;
    textColumn.Binding = new Binding("");
    textColumn.Width = 100;
    System.Windows.Controls.Primitives.DataGridColumnHeader header = new System.Windows.Controls.Primitives.DataGridColumnHeader();
    Style headerStyle = new System.Windows.Style();
    headerStyle.TargetType = header.GetType();
    headerStyle.Setters.Add(new Setter(HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
    textColumn.HeaderStyle = headerStyle;
    log_grid.Columns.Add(textColumn);
}
chListView.ItemsSource = chList;
<ListView x:Name="chListView" 
      ItemsSource="{Binding chlist2}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding isCheck}"
                          Width="120" 
                          Content="{Binding ttl}"
                          Cursor="Hand"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
<DataGrid x:Name="log_grid" 
    Grid.Row="1"
    AlternatingRowBackground="LightGray"
    HorizontalGridLinesBrush="LightGray"
    VerticalGridLinesBrush="LightGray" 
    HorizontalScrollBarVisibility="Visible"
    CanUserReorderColumns="True">
</DataGrid>

Как связать чекбоксы и столбцы чтобы при checked/unchecked соот-е столбцы DataGrid показывались/скрывались?

Answer 1

По хорошему, у вас должна быть ViewModel с нужными вам колонками, которые вы уже можете биндить как и куда хотите.

Но если вы хотите идти неверным путем и вас это устраивает, то как пример вредного совета могу подсказать, что ваш грид уже содержит колонки, потому можно просто привязаться к нему, и вывести его колонки в отдельный лист, например

<Grid>
    <Grid.Resources>
        <local:VisibilityToBooleanConverter x:Key="BoolToVis" />
    </Grid.Resources>
    <StackPanel Orientation="Vertical">
        <ListView ItemsSource="{Binding Columns, ElementName=grid}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding Visibility, Converter={StaticResource BoolToVis}}"
                      Width="120" 
                      Content="{Binding Header}"
                      Cursor="Hand"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    <DataGrid ItemsSource="{Binding Foos}" Name="grid"></DataGrid>
    </StackPanel>
</Grid>

Где код самописного конвертера:

public class VisibilityToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value is Visibility) && (Visibility)value == Visibility.Visible;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (value is bool && (bool) value) ? Visibility.Visible : Visibility.Collapsed;
    }
}

Результат

upd

Полный код разметки из примера

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication5"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>
            <local:VisibilityToBooleanConverter x:Key="BoolToVis" />
        </Grid.Resources>
        <StackPanel Orientation="Vertical">
            <ListView ItemsSource="{Binding Columns, ElementName=grid}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding Visibility, Converter={StaticResource BoolToVis}}"
                          Width="120" 
                          Content="{Binding Header}"
                          Cursor="Hand"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        <DataGrid ItemsSource="{Binding Foos}" Name="grid"></DataGrid>
        </StackPanel>
    </Grid>
</Window>

Полный код code-behind

using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Data;
namespace WpfApplication5
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = this;
        }
        public Foo[] Foos { get; set; } = new Foo[] { new Foo() { Id = 1 }, new Foo() { Id = 2 }, };
    }
    public class Foo
    {
        public int Id { get; set; }
        public string NickName { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class VisibilityToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (value is Visibility) && (Visibility)value == Visibility.Visible;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (value is bool && (bool) value) ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}
READ ALSO
Отношение один к разным типам объектов

Отношение один к разным типам объектов

Я не знаю, есть ли какой-то готовый термин, поэтому в заголовок вынес "один-к-разным-типам-объектов", но это не термин из EF-диаграмм (один-ко-многим,...

134
Как проксировать сайт с заданными cookies?

Как проксировать сайт с заданными cookies?

Есть сервис например: myservicecom, я авторизован в этом сервисе

148
Сохранит куки curl php

Сохранит куки curl php

Почему такой код не сохраняет куки?

157