【问题标题】:WPF Code-Behind data binding with AutoGeneratedColumns not working带有 AutoGeneratedColumns 的 WPF 代码隐藏数据绑定不起作用
【发布时间】:2020-04-23 13:38:48
【问题描述】:

我正在尝试实现一些简单的事情,并且我相信我的方法可能是错误的。我正在创建一个数据网格,其中第一列的宽度与其他列分开。我正在使用 AutoGenerateColumns=true,因为它简化了我的工作。我不能使用纯 XAML,因为在运行前我不知道列的数量,并且我无法连接 XAML 和 AutoGenerateColumns,因此它将使用第一列的布局,然后生成其余列。

我的方法:

1) 创建两个彼此相邻的数据网格 - 这种方法的问题是需要管理 2 个单独的数据网格,我看到滚动和调整它们的大小的问题,所以我决定改变我的方法,以保持一切都在一个 DataGrid,因为数据相互关联。

2) 尝试从 Code-Behind 获取 Datagrid 对象,以便我可以从 ViewModel 类中设置 Width 属性,这会破坏 MVVM 模型,并且我也很难实现

3) 当前方法 - 使用 AutoGeneratingColumn 事件,我捕获第一列并尝试绑定到它的 WidthProperties。不幸的是,这似乎不起作用,我不知道为什么。

这是包含 DataGrid 的 XAML 的代码隐藏文件

 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";
            }
        }

这是我在 ViewModel 中的属性。在调试绑定源时,它附加到正确的类,我看到了我的所有属性。它还会更改右列的标题。


 private int _DateColumnWidth;

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

我设置调试器显示所有数据绑定跟踪信息,没有出现问题,但宽度没有更新。 我做错了什么?

【问题讨论】:

  • 你真的需要绑定吗?如果没有,为什么不直接在 AutoGeneratingColumn 事件中设置宽度?
  • 因为我之后要调整整个网格的大小,并且我希望能够调整第一列

标签: c# wpf data-binding datagrid


【解决方案1】:

我根据您的代码创建了一个模型,并且效果很好。然后我仔细看了看,发现你有这个:

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

ColumnDefinition 是错误的对象。应该是DataGridColumn:

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

这是我的测试。网格的第一列绑定到ViewModel 上的ColumnWidth 属性。网格下方有一个 Slider 控件,具有相同的绑定。滑动滑块会改变第一列的宽度。

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 列宽(用户无法更改这些 - 并且确实无法更改宽度,因为 Min 和 Max宽度设置为相同的值)。如果您打算以两种方式绑定宽度,那么您将需要绑定到 WidthProperty 依赖属性而不是 Min/MaxWidthProperty DPs(但是,您可能需要一个值转换器,因为 Width 是 GridLength 而不是纯数字。如果这是您尝试做的,请说出来,我会看看是否可以相应地更新答案。

【讨论】:

  • 这解决了问题!!!非常感谢您投入时间并帮助我!我不敢相信我犯了这样的错误!希望我能投票 10 次!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 2014-06-05
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2012-07-15
相关资源
最近更新 更多