我试图将一个数据网格的标题宽度绑定到另一个数据网格的标题.
所以,我为父数据网格的每一行添加了一个数据网格.现在,我试图使用Parent标头的列控制子数据网格的列大小.
所以在最后一列的headertemplate中,我添加了一个只有列标题的数据网格,没有行.在本专栏的celltemplate中,我添加了另一个数据网格,没有标题,只有数据行.
在调整headertemplate datagrid列标题的大小时,XAML中是否有任何方法可以调整celltemplate的datagrid列的大小.
在SO上读了很多关于CodeProject等的帖子,但是我无法使它工作.有可能吗?
XAML
C#类数据例如:
namespace WpfApplication1 { public class Assets { public ListAllAssets { get; set; } public Assets() { AllAssets = new List (); for (int i = 1; i < 3; i++) { Asset asset = new Asset(); asset.id = i; asset.name = "asset " + i.ToString(); for (int x = 1; x < 3; x++) { MonthsData months = new MonthsData(); months.MonthName = "Month " + x.ToString(); months.value = x; asset.months.Add(months); } AllAssets.Add(asset); } } } public class Asset { public int id { get; set; } public string name { get; set; } public List months { get; set; } public Asset() { months = new List (); } } public class MonthsData { public string MonthName { get; set; } public int value { get; set; } } }
假设您可以在ViewModel中定义几个属性
public class Assets : MVVM.ViewModel.ViewModelBase { public ListAllAssets { get; set; } private double col1Width; private double col2Width; public double Col1Width { get { return col1Width; } set { col1Width = value; OnPropertyChanged("Col1Width"); } } public double Col2Width { get { return col2Width; } set { col2Width = value; OnPropertyChanged("Col2Width"); } }
然后,您将能够通过帮助程序从XAML读取Load事件的实际宽度
private void Grid_Loaded(object sender, RoutedEventArgs e) { var dg = FindVisualChildByName(Test, "dgC"); assets.Col1Width = dg.Columns[0].ActualWidth; assets.Col2Width = dg.Columns[1].ActualWidth; }
并将它们从网格的DataContext中设置回XAML绑定
正如下面的评论中正确指出的那样,我们可以避免"仅与ViewModel中的View相关的属性"并管理任意(但固定)数量的列,以便dgC和dgH的宽度(假设它们具有相同的宽度)列数)是链接的
private void Grid_Loaded(object sender, RoutedEventArgs e) { var dgC = FindVisualChildByName(Test, "dgC"); var dgH = FindVisualChildByName (Test, "dgH"); for (int i = 0; i < dgC.Columns.Count; i++) { dgH.Columns[i].Width = dgC.Columns[i].ActualWidth; } }
在这种情况下,不再需要VM绑定
这更复杂,所以请在严格要求的情况下继续.
让我们更改实用程序,以便它将返回所有datagrid dgCs(每行有一个dgC)
public static IEnumerableFindVisualChildByName (DependencyObject parent, string name) where T : DependencyObject { List list = new List (); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); string controlName = child.GetValue(Control.NameProperty) as string; if (controlName == name) { list.Add(child as T); } else { IEnumerable result = FindVisualChildByName (child, name); if (result != null) list.AddRange(result); } } return list; }
现在我们将为实际的宽度变化定义一个依赖属性
private bool _columnWidthChanging; private void ColumnWidthPropertyChanged(object sender, EventArgs e) { // listen for when the mouse is released _columnWidthChanging = true; if (sender != null) Mouse.AddPreviewMouseUpHandler(this, BaseDataGrid_MouseLeftButtonUp); } void BaseDataGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (_columnWidthChanging) { _columnWidthChanging = false; var dgCs = FindVisualChildByName(Test, "dgC"); var dgH = FindVisualChildByName (Test, "dgH").First(); foreach (var dgC in dgCs) { for (int i = 0; i < dgC.Columns.Count; i++) { var column = dgH.Columns[i]; dgC.Columns[i].Width = column.ActualWidth; } } } } private void Grid_Loaded(object sender, RoutedEventArgs e) { var dgC = FindVisualChildByName (Test, "dgC").First(); var dgH = FindVisualChildByName (Test, "dgH").First(); for (int i = 0; i < dgC.Columns.Count; i++) { var column = dgC.Columns[i]; dgH.Columns[i].Width = column.ActualWidth; PropertyDescriptor pd = DependencyPropertyDescriptor .FromProperty(DataGridColumn.ActualWidthProperty, typeof(DataGridColumn)); //Add a listener for this column's width pd.AddValueChanged(dgH.Columns[i], new EventHandler(ColumnWidthPropertyChanged)); }