问题 WPF DataGrid同步列宽度
我有两个WPF工具包 DataGrids
我希望当用户调整第一个网格中第一列的大小时,它会调整第二个网格中第一列的大小。我试过绑定宽度 DataGridColumn
在第二个网格中第一个网格中的相应列,但它不起作用。我更喜欢使用所有xaml,但我也可以使用后面的代码。
<tk:DataGrid Width="100" Height="100">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn x:Name="Column1" Width="50"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
<tk:DataGrid Width="100" Height="100">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn x:Name="Column1Copy" Width="{Binding Path=ActualWidth, ElementName=Column1}"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
我也试过绑定 Width
代替 ActualWidth
,但都不起作用。
任何帮助是极大的赞赏。
2313
2018-01-05 20:00
起源
答案:
好吧,我不认为使用直接XAML是可能的,但我仍然觉得它应该是因为 DataGridColumn
确实来自 DependencyObject
。我确实找到了一种以编程方式进行编程的方法。我对此并不感到兴奋,但它有效:
DataGridColumn.WidthProperty.AddValueChanged(upperCol, delegate
{
if (changing) return;
changing = true;
mainCol.Width = upperCol.Width;
changing = false;
});
DataGridColumn.WidthProperty.AddValueChanged(mainCol, delegate
{
if (changing) return;
changing = true;
upperCol.Width = mainCol.Width;
changing = false;
});
public static void AddValueChanged(this DependencyProperty property, object sourceObject, EventHandler handler)
{
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(property, property.OwnerType);
dpd.AddValueChanged(sourceObject, handler);
}
12
2018-01-12 16:58
答案:
好吧,我不认为使用直接XAML是可能的,但我仍然觉得它应该是因为 DataGridColumn
确实来自 DependencyObject
。我确实找到了一种以编程方式进行编程的方法。我对此并不感到兴奋,但它有效:
DataGridColumn.WidthProperty.AddValueChanged(upperCol, delegate
{
if (changing) return;
changing = true;
mainCol.Width = upperCol.Width;
changing = false;
});
DataGridColumn.WidthProperty.AddValueChanged(mainCol, delegate
{
if (changing) return;
changing = true;
upperCol.Width = mainCol.Width;
changing = false;
});
public static void AddValueChanged(this DependencyProperty property, object sourceObject, EventHandler handler)
{
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(property, property.OwnerType);
dpd.AddValueChanged(sourceObject, handler);
}
12
2018-01-12 16:58
你可以使用 DataGrid
LayoutUpdated
操纵关于列宽的其他对象的方法。
private void dataGrid1_LayoutUpdated(object sender, EventArgs e)
{
for(int i = 0 ; i < dataGrid1.Columns.Count && i < dataGrid2.Columns.Count ; ++i)
dataGrid2.Columns[i].Width = dataGrid1.Columns[i].ActualWidth;
}
4
2017-11-27 04:10
我试过这个:
<tk:DataGrid Width="100" Height="100" x:Name="Grid1" Grid.Column="0">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn x:Name="Column1" Width="50"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
<tk:DataGrid Width="100" Height="100" x:Name="Grid2" Grid.Column="1">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn x:Name="Column1Copy" Width="{Binding Mode=TwoWay, Path=Columns[0].ActualWidth, ElementName=Grid1}"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
但是,它看起来像 DataGridColumn
s不是源于 FrameworkElement
而是衍生自 DependencyObject
,以这种方式绑定不可用。
1
2018-01-05 23:19
如果要在XAML中绑定列Width属性,请在2中 DataGrid
比你必须做的更多。
在第一个 DataGrid
命名 DataGridTextColumn
:
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Col1"/>
</DataGrid.Columns>
</DataGrid>
在第二 DataGrid
添加一个 DiscreteObjectKeyFrame
指向上面提到的列作为资源,并使用以下 Binding
至 Width
物业 DataGridTextColumn
你想“链接”:
<DataGrid>
<DataGrid.Resources>
<DiscreteObjectKeyFrame x:Key="proxyCol1" Value="{Binding ElementName=Col1}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Width="{Binding Path=Value.Width, Mode=TwoWay, Source={StaticResource proxyCol1}}"/>
</DataGrid.Columns>
</DataGrid>
0
2017-12-21 08:55
我做了一个快速的解决方案来使用附加的行为,灵感来自上面的Ahmed回答。
public class DataGridWidthSyncronizerBehavior
{
public static readonly DependencyProperty SyncronizeWidthWithProperty =
DependencyProperty.RegisterAttached("SyncronizeWidthWith",
typeof(DataGrid),
typeof(DataGridWidthSyncronizerBehavior),
new UIPropertyMetadata(null, SyncronizeWidthWithChanged));
public static void SetSyncronizeWidthWith(DependencyObject target, DataGrid value)
{
target.SetValue(SyncronizeWidthWithProperty, value);
}
public static DataGrid GetSyncronizeWidthWith(DependencyObject target)
{
return (DataGrid)target.GetValue(SyncronizeWidthWithProperty);
}
private static void SyncronizeWidthWithChanged(DependencyObject obj, DependencyPropertyChangedEventArgs dpargs)
{
if (!(obj is DataGrid sourceDataGrid))
return;
if (!(sourceDataGrid.GetValue(SyncronizeWidthWithProperty) is DataGrid targetDataGrid))
return;
void Handler(object sender, EventArgs e)
{
for (var i = 0; i < sourceDataGrid.Columns.Count && i < targetDataGrid.Columns.Count; ++i)
targetDataGrid.Columns[i].Width = sourceDataGrid.Columns[i].ActualWidth;
}
sourceDataGrid.LayoutUpdated -= Handler;
sourceDataGrid.LayoutUpdated += Handler;
}
}
XAML:
<DataGrid local:DataGridWidthSyncronizerBehavior.SyncronizeWidthWith="{Binding ElementName=SyncronizedHeaderGrid}">
<DataGrid.Columns>
<DataGridTextColumn Header="Header 1"
Binding="{Binding Item1}" />
<DataGridTextColumn Header="Header 2"
Binding="{Binding Item2}"/>
<DataGridTextColumn Header="Header 3"
Binding="{Binding Item3}"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid x:Name="SyncronizedHeaderGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Header 1"
Binding="{Binding Item1}" />
<DataGridTextColumn Header="Header 2"
Binding="{Binding Item2}"/>
<DataGridTextColumn Header="Header 3"
Binding="{Binding Item3}"/>
</DataGrid.Columns>
</DataGrid>
现在,第二个DataGrids,标题和单元格宽度与第一个网格标题宽度同步。
0
2017-08-08 10:42
我找到了这个问题的解决方案,还有一个很酷的解决方案:-)
您可以下载WPF工具包并获取DataGrid的代码。
获得代码之后,您只需将DataGridColumn类更改为继承FrameworkElement而不是DependencyObject。
一旦你这样做 - 你只剩下一个问题,列的DataContext将不会被初始化,因为列不是逻辑树的一部分,将它添加到逻辑树将解决这个问题。
你可以这样做:
OnColumnInitialization的位置是:
private void OnColumnInitialization(对象发送者,EventArgs e)
{
AddLogicalChild(发送者);
}
现在它是逻辑树的一部分,你有相同的数据上下文,你可以使用绑定
宽度属性。
如果所有都绑定到相同的宽度 - 您可以完全同步列的宽度。
这对我有用:-)
吉利
-2
2018-06-16 23:12