Datagridcolumn:通过 BindingProxy 绑定可见性和宽度显示不同的行为
Datagridcolumn: Binding Visibility and Width via BindingProxy show different behavior
由于数据网格的列不在数据网格的可视化树中,我正在使用这种绑定代理的方法来绑定 DataGridTextColumn
.
的可见性
出于某种原因,我想了解相同的方法确实适用于 Visibility
但不适用于专栏的 Width
属性。
有人可以向我解释这种不同的行为吗?
代码示例
c#
class BindingProxy : Freezable
{
#region Override of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion //Override of Freezable
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
public class Column : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected internal void OnPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
public Column(bool visible = true)
{
if (visible == true)
Visible = Visibility.Visible;
else
Visible = Visibility.Collapsed;
Width = 200;
}
public Visibility Visible
{
get { return m_visible; }
set { m_visible = value; OnPropertyChanged("Visible"); }
}
Visibility m_visible;
public double Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
double m_width;
}
只是为了更容易重现
public partial class MainWindow : Window
{
public MainWindow()
{
Lines = new ObservableCollection<tableline>();
for (int i = 0; i< 5; i++)
Lines.Add(new tableline());
Columns = new List<Column>();
Columns.Add(new Column(true));
Columns.Add(new Column(false));
InitializeComponent();
DataContext = this;
}
public List<Column> Columns { get; set; }
public ObservableCollection<tableline>Lines { get; set; }
}
public class tableline
{
public tableline()
{
Result = new List<string>();
int colCount = 2;
for (int i = 0; i < colCount; i++)
{
Result.Add(i.ToString() + " some text");
}
}
public List<string> Result { get; set; }
}
xaml
<DataGrid ItemsSource="{Binding Lines}" AutoGenerateColumns="False" >
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[0]}" Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}}" />
<DataGridTextColumn Header="ProductId2" Binding="{Binding Path=Result[1]}" Visibility="{Binding Data.Columns[1].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[1].Width, Source={StaticResource proxy}}"/>
</DataGrid.Columns>
</DataGrid>
只是想让你知道我最初的目标是什么。我想将所有列的宽度设置为自动,但在绘制数据网格期间使用 "maximum" 列宽。但是,用户应该可以调整大小超过此限制。这就是为什么我不能使用 MaxColumnWidth
所以我认为实现这一点的最简单方法是读取每一列的宽度并将其设置为 "maximum" 值(如果它大于限制)。
DataGridColumn
的 Width
属性 的类型是 DataGridLength
而不是 double
。
更改源类型属性:
public DataGridLength Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
DataGridLength m_width;
和Binding
的Mode
:
<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[1]}"
Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}"
Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}, Mode=TwoWay}" />
由于数据网格的列不在数据网格的可视化树中,我正在使用这种绑定代理的方法来绑定 DataGridTextColumn
.
出于某种原因,我想了解相同的方法确实适用于 Visibility
但不适用于专栏的 Width
属性。
有人可以向我解释这种不同的行为吗?
代码示例
c#
class BindingProxy : Freezable
{
#region Override of Freezable
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion //Override of Freezable
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
public class Column : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected internal void OnPropertyChanged(string propertyname)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
public Column(bool visible = true)
{
if (visible == true)
Visible = Visibility.Visible;
else
Visible = Visibility.Collapsed;
Width = 200;
}
public Visibility Visible
{
get { return m_visible; }
set { m_visible = value; OnPropertyChanged("Visible"); }
}
Visibility m_visible;
public double Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
double m_width;
}
只是为了更容易重现
public partial class MainWindow : Window
{
public MainWindow()
{
Lines = new ObservableCollection<tableline>();
for (int i = 0; i< 5; i++)
Lines.Add(new tableline());
Columns = new List<Column>();
Columns.Add(new Column(true));
Columns.Add(new Column(false));
InitializeComponent();
DataContext = this;
}
public List<Column> Columns { get; set; }
public ObservableCollection<tableline>Lines { get; set; }
}
public class tableline
{
public tableline()
{
Result = new List<string>();
int colCount = 2;
for (int i = 0; i < colCount; i++)
{
Result.Add(i.ToString() + " some text");
}
}
public List<string> Result { get; set; }
}
xaml
<DataGrid ItemsSource="{Binding Lines}" AutoGenerateColumns="False" >
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[0]}" Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}}" />
<DataGridTextColumn Header="ProductId2" Binding="{Binding Path=Result[1]}" Visibility="{Binding Data.Columns[1].Visible, Source={StaticResource proxy}}" Width="{Binding Data.Columns[1].Width, Source={StaticResource proxy}}"/>
</DataGrid.Columns>
</DataGrid>
只是想让你知道我最初的目标是什么。我想将所有列的宽度设置为自动,但在绘制数据网格期间使用 "maximum" 列宽。但是,用户应该可以调整大小超过此限制。这就是为什么我不能使用 MaxColumnWidth
所以我认为实现这一点的最简单方法是读取每一列的宽度并将其设置为 "maximum" 值(如果它大于限制)。
DataGridColumn
的 Width
属性 的类型是 DataGridLength
而不是 double
。
更改源类型属性:
public DataGridLength Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
DataGridLength m_width;
和Binding
的Mode
:
<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[1]}"
Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}"
Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}, Mode=TwoWay}" />