AsV*_*leO 5 c# wpf datagrid scroll width
滚动垂直滚动条时,DataGrid如果新可见行中的内容较大且超出以前的列宽,则会自动扩展列宽.没关系.
但是,如果滚动所有较大的行并且新的可见行具有较小的内容宽度,DataGrid则不会减小列宽.有办法实现这个吗?
附加的行为实施将是伟大的.
代码behing:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
var persons = new List<Person>();
for (var i = 0; i < 20; i++)
persons.Add(new Person() {Name = "Coooooooooooooool", Surname = "Super"});
for (var i = 0; i < 20; i++)
persons.Add(new Person() {Name = "Cool", Surname = "Suuuuuuuuuuuuuuper"});
for (var i = 0; i < 20; i++)
persons.Add(new Person() {Name = "Coooooooooooooool", Surname = "Super"});
DG.ItemsSource = persons;
}
public class Person
{
public string Name { get; set; }
public string Surname { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
XAML:
<Window
x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="400"
Height="200"
mc:Ignorable="d">
<Grid>
<DataGrid
x:Name="DG"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserSortColumns="False" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
小智 5
将LoadingRow属性添加到数据网格:
<DataGrid x:Name="DG"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserSortColumns="False" LoadingRow="DG_LoadingRow">
</DataGrid>
Run Code Online (Sandbox Code Playgroud)
然后在后面的代码中添加这段代码:
private void DG_LoadingRow(object sender, DataGridRowEventArgs e)
{
foreach (DataGridColumn c in DG.Columns)
c.Width = 0;
DG.UpdateLayout();
foreach (DataGridColumn c in DG.Columns)
c.Width = DataGridLength.Auto;
}
Run Code Online (Sandbox Code Playgroud)
这绝对不是最干净的解决方案,但它会调整滚动时可见的列的大小。
希望这可以帮助。
您能否将其包装到附加行为中?
1)第一个选项是使用Attached Property。
public class DataGridHelper : DependencyObject
{
public static readonly DependencyProperty SyncedColumnWidthsProperty =
DependencyProperty.RegisterAttached(
"SyncedColumnWidths",
typeof(Boolean),
typeof(DataGridHelper),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(OnSyncColumnsChanged)
));
private static void OnSyncColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DataGrid dataGrid)
{
dataGrid.LoadingRow += SyncColumnWidths;
}
}
private static void SyncColumnWidths(object sender, DataGridRowEventArgs e)
{
var dataGrid = (DataGrid)sender;
foreach (DataGridColumn c in dataGrid.Columns)
c.Width = 0;
e.Row.UpdateLayout();
foreach (DataGridColumn c in dataGrid.Columns)
c.Width = DataGridLength.Auto;
}
public static void SetSyncedColumnWidths(UIElement element, Boolean value)
{
element.SetValue(SyncedColumnWidthsProperty, value);
}
}
Run Code Online (Sandbox Code Playgroud)
用法
<DataGrid
ext:DataGridHelper.SyncedColumnWidths="True"
... />
Run Code Online (Sandbox Code Playgroud)
2)或者,行为提供了一种更加封装的方式来扩展功能(需要System.Windows.Interactivity)。
using System.Windows.Interactivity;
...
public class SyncedColumnWidthsBehavior : Behavior<DataGrid>
{
protected override void OnAttached()
{
this.AssociatedObject.LoadingRow += this.SyncColumnWidths;
}
protected override void OnDetaching()
{
this.AssociatedObject.LoadingRow -= this.SyncColumnWidths;
}
private void SyncColumnWidths(object sender, DataGridRowEventArgs e)
{
var dataGrid = this.AssociatedObject;
foreach (DataGridColumn c in dataGrid.Columns)
c.Width = 0;
e.Row.UpdateLayout();
foreach (DataGridColumn c in dataGrid.Columns)
c.Width = DataGridLength.Auto;
}
}
Run Code Online (Sandbox Code Playgroud)
用法
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...
<DataGrid
... >
<i:Interaction.Behaviors>
<ext:SyncedColumnWidthsBehavior />
</i:Interaction.Behaviors>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)
行为提供了一种释放事件处理程序的干净方法。尽管在这种情况下,即使我们不取消订阅附加属性,我们也不会造成内存泄漏(参考不取消注册事件处理程序是否不好?)。