WPF Code-Behind привязка данных с AutoGeneratedColumns не работает - PullRequest
1 голос
/ 06 января 2020

Я пытаюсь достичь чего-то более простого и считаю, что мой подход может быть неправильным. Я создаю сетку данных, где первый столбец имеет ширину, отличную от других. Я использую AutoGenerateColumns = true, поскольку это упрощает мою работу. Я не могу использовать чистый XAML, так как не знаю количество столбцов до времени выполнения, и я не смог соединить XAML и AutoGenerateColumns, поэтому он будет использовать макет первого столбца, а затем сгенерировать остальные.

My подходы:

1) Создайте две сетки данных рядом друг с другом - проблема с этим подходом заключается в необходимости управлять 2 отдельными сетками данных, я видел проблемы с прокруткой и настройкой их размеров, поэтому я решил изменить свой подход , чтобы сохранить все внутри одной DataGrid, поскольку данные связаны друг с другом.

2) Попытка получить объект Datagrid из Code-Behind, чтобы я мог установить свойство Width из класса ViewModel, это приведет к поломке MVVM модели, а также для меня было трудно реализовать

3) Текущий подход - используя событие AutoGeneratingColumn , я фиксирую первый столбец и пытаюсь привязаться к его WidthProperties. К сожалению, это, похоже, не работает, и я не знаю, почему.

Это мой файл кода для XAML, содержащий DataGrid

 private void DG1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            string headername = e.Column.Header.ToString();
            //Cancel the column you don't want to generate
            if (headername == "DATE")
            {
                Binding binding = new Binding("DateColumnWidth");
                binding.Source = DataGrid.DataContext; // DataGrid is the name of the DataGrid
                binding.Mode = BindingMode.TwoWay;

                binding.Path = new PropertyPath("DateColumnWidth");
                BindingOperations.SetBinding(e.Column, ColumnDefinition.MinWidthProperty, binding);
                BindingOperations.SetBinding(e.Column, ColumnDefinition.MaxWidthProperty, binding);
                e.Column.Header = "Test";
            }
        }

Это мой Proprty в ViewModel , При отладке источника привязки он подключается к нужному классу, и я вижу все свои свойства. Это также меняет заголовок правой колонки.


 private int _DateColumnWidth;

        public int DateColumnWidth
        {
            get { return _DateColumnWidth; }
            set
            {
                _DateColumnWidth = value;
                RaisePropertyChanged("DateColumnWidth");
            }
        }

Я установил отладчик, чтобы показать мне всю информацию о трассировке привязки данных, никаких проблем не возникает, но ширина не обновляется. Что я делаю не так?

1 Ответ

1 голос
/ 06 января 2020

Я создал макет на основе вашего кода, и он работал. Затем я посмотрел повнимательнее и понял, что у вас есть это:

BindingOperations.SetBinding(e.Column, ColumnDefinition.MinWidthProperty, binding);

ColumnDefinition - неправильный объект. Это должно быть DataGridColumn:

BindingOperations.SetBinding(e.Column, DataGridColumn.MaxWidthProperty, binding);

Вот мой тест. Первый столбец сетки привязан к свойству ColumnWidth в ViewModel. Под сеткой находится элемент управления Slider с той же привязкой. Сдвиг ползунка изменяет ширину первого столбца.

enter image description here

MainWindow.xaml:

<Window x:Class="SO_59604847_DataGridBoundColumnWidth.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SO_59604847_DataGridBoundColumnWidth"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DataGrid
            AutoGenerateColumns="True"
            ItemsSource="{Binding GridItems}"
            AutoGeneratingColumn="DataGrid_AutoGeneratingColumn">
        </DataGrid>
        <Slider Grid.Row="1" Minimum="1" Maximum="1000" Value="{Binding ColumnWidth}" />
    </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.Column.Header.ToString() == "ColumnOne")
        {
            var binding = new Binding("ColumnWidth");
            binding.Source = this.DataContext;
            BindingOperations.SetBinding(e.Column, DataGridColumn.MinWidthProperty, binding);
            BindingOperations.SetBinding(e.Column, DataGridColumn.MaxWidthProperty, binding);
        }
    }
}

ViewModel.cs:

public class ViewModel : INotifyPropertyChanged
{
    private double _columnWidth;
    public double ColumnWidth 
    {
        get { return _columnWidth; }
        set { _columnWidth = value; FirePropertyChanged(); }
    }

    private List<GridItem> _gridItems = new List<GridItem>()
        {
            new GridItem() { ColumnOne = "1.1", ColumnTwo = "1.2", ColumnThree = "1.3" },
            new GridItem() { ColumnOne = "2.1", ColumnTwo = "2.2", ColumnThree = "2.3" },
            new GridItem() { ColumnOne = "3.1", ColumnTwo = "3.2", ColumnThree = "3.3" }
        };

    public List<GridItem> GridItems 
    { 
        get { return _gridItems; }
    }

    private void FirePropertyChanged([CallerMemberName] string caller = "")
    {
        PropertyChanged(this, new PropertyChangedEventArgs(caller));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class GridItem
{
    public string ColumnOne { get; set; }
    public string ColumnTwo { get; set; }
    public string ColumnThree { get; set; }
}

Это не делает двустороннее связывание, потому что это не имеет смысла, если вы привязываетесь к ширине столбцов Min и Max ( пользователь не может изменить их - и действительно не может изменить ширину, потому что минимальная и максимальная ширины установлены на одно и то же значение). Если вы намеревались связать ширину в двух направлениях, вам нужно будет привязать свойство зависимости WidthProperty, а не DP / Min / MaxWidthProperty (хотя вам может потребоваться преобразователь значений, потому что Width - это GridLength, а не просто так. Скажите, если это то, что вы пытались сделать, и я посмотрю, смогу ли я соответствующим образом обновить ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...