[英]WPF Code-Behind data binding with AutoGeneratedColumns not working
I am trying to achieve rather something simple, and I believe that my approach might be wrong.我正在努力实现一些简单的东西,我相信我的方法可能是错误的。 I am creating a datagrid, where the first column has a seperate width from the other ones.我正在创建一个数据网格,其中第一列与其他列具有不同的宽度。 I am using AutoGenerateColumns=true, as it simplifies my work.我正在使用 AutoGenerateColumns=true,因为它简化了我的工作。 I cannot use pure XAML as I do not know the amount of columns before runtime, and I was not able to connect XAML and AutoGenerateColumns, so it would use the first column's layout, and then generate the rest.我不能使用纯 XAML,因为我不知道运行前的列数,而且我无法连接 XAML 和 AutoGenerateColumns,因此它将使用第一列的布局,然后生成其余的列。
My approaches:我的方法:
1) Create two data grids next to each other - the issue with that approach is the need to manage 2 seperate datagrids, I saw issues with scrolling and adjusting their sizes, so I decided to change my approach, to keep everyhting within one DataGrid as the data relates to each other. 1)创建两个相邻的数据网格 - 这种方法的问题是需要管理 2 个单独的数据网格,我看到滚动和调整它们的大小的问题,所以我决定改变我的方法,将所有数据都保留在一个数据网格中数据相互关联。
2) Trying to get the Datagrid object from Code-Behind so I can set the Width property from the ViewModel class, this would break the MVVM model, and also was difficult for my to implement 2) 尝试从 Code-Behind 获取 Datagrid 对象,以便我可以从 ViewModel 类中设置 Width 属性,这会破坏 MVVM 模型,而且我也很难实现
3) Current approach - using the AutoGeneratingColumn event, I capture the first column and try to bind to its WidthProperties. 3) 当前方法 - 使用AutoGeneratingColumn事件,我捕获第一列并尝试绑定到其 WidthProperties。 Unfortunately this does not seem to work, and I do not know why.不幸的是,这似乎不起作用,我不知道为什么。
This is my Code-Behind file for the XAML containing the DataGrid这是包含 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";
}
}
This is my Proprty in the ViewModel.这是我在 ViewModel 中的属性。 Whilst debugging the binding source, it attaches to the right class and I see all my properties.在调试绑定源时,它附加到正确的类,我会看到我的所有属性。 It also changes the header of the right column.它还会更改右列的标题。
private int _DateColumnWidth;
public int DateColumnWidth
{
get { return _DateColumnWidth; }
set
{
_DateColumnWidth = value;
RaisePropertyChanged("DateColumnWidth");
}
}
I set the debugger to show me all the data binding tracing information, no problems arise, but the width is not updating.我将调试器设置为向我显示所有数据绑定跟踪信息,没有出现问题,但宽度没有更新。 What am I doing wrong?我究竟做错了什么?
I created a mock up based on your code and it worked.我根据您的代码创建了一个模型并且它有效。 Then I looked more closely and realised you have this:然后我更仔细地看了看,意识到你有这个:
BindingOperations.SetBinding(e.Column, ColumnDefinition.MinWidthProperty, binding);
ColumnDefinition
is the wrong object. ColumnDefinition
是错误的对象。 It should be DataGridColumn
:它应该是DataGridColumn
:
BindingOperations.SetBinding(e.Column, DataGridColumn.MaxWidthProperty, binding);
Here is my test.这是我的测试。 The grid's first column is bound to a ColumnWidth
property on ViewModel
.网格的第一列绑定到ViewModel
上的ColumnWidth
属性。 There is a Slider control below the grid with the same binding.网格下方有一个具有相同绑定的 Slider 控件。 Sliding the slider changes the first column's width.滑动滑块会更改第一列的宽度。
MainWindow.xaml:主窗口.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:主窗口.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:视图模型.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; }
}
It does not do two-way binding because that doesn't make sense if you're binding to the Min and Max column widths (the user can't change these - and indeed cannot change the width because the Min and Max widths are set to the same value).它不进行双向绑定,因为如果您绑定到最小和最大列宽(用户无法更改这些 - 并且实际上无法更改宽度,因为设置了最小和最大宽度),这没有意义到相同的值)。 If your intention was to bind the width two-ways then you will need to bind to the WidthProperty
dependency property and not the Min/MaxWidthProperty DPs (though, you may need a value converter then because Width is a GridLength
not a plain number. Say so if that is what you were trying to do and I'll see if I can update the answer accordingly.如果您打算以两种方式绑定宽度,那么您将需要绑定到WidthProperty
依赖项属性而不是 Min/MaxWidthProperty DP(不过,您可能需要一个值转换器,因为 Width 是一个GridLength
而不是一个普通数字。说所以如果这就是你想要做的,我会看看我是否可以相应地更新答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.