Datagridcolumn:通过BindingProxy的绑定可见性和宽度显示不同的行为 [英] Datagridcolumn: Binding Visibility and Width via BindingProxy show different behavior
问题描述
由于数据网格的列不在数据网格的可视树中,所以我正在使用这种绑定代理方法来绑定 DataGridTextColumn
的可见性。 / p>
出于某种原因,我想了解相同的方法确实对 Visibility 有用
,但不适用于列的 Width
属性。
有人可以向我解释这种不同的行为吗?
代码示例
c#
class BindingProxy:可冻结
{
#区域可冻结
的保护覆盖Freezable CreateInstanceCore()
{
return new BindingProxy();
}
#endregion //覆盖Freezable
公共对象数据
{
get {return(object)GetValue(DataProperty); }
set {SetValue(DataProperty,value); }
}
公共静态只读DependencyProperty DataProperty = DependencyProperty.Register( Data,typeof(object),typeof(BindingProxy),新的UIPropertyMetadata(null));
}
公共类列:INotifyPropertyChanged
{
公共事件PropertyChangedEventHandler PropertyChanged;
受保护的内部无效OnPropertyChanged(字符串属性名)
{
if(PropertyChanged!= null)
PropertyChanged(this,new PropertyChangedEventArgs(propertyname));
}
public Column(bool visible = true)
{
if(visible == true)
Visible = Visibility.Visible;
else
Visible = Visibility.Collapsed;
宽度= 200;
}
公共可见性
{
get {return m_visible; }
set {m_visible = value; OnPropertyChanged( Visible); }
}
可见性m_visible;
public double宽度
{
get {return m_width; }
set {m_width = value; OnPropertyChanged( Width); }
}
double m_width;
}
只是为了使其更易于复制
公共部分类MainWindow:Window
{
public MainWindow()
{
行= 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>列{get;组; }
public ObservableCollection< tableline> Lines {get;组; }
}
公共类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>结果{get;组; }
}
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>
只是让您知道我的最初目标是什么。我想将所有列的宽度都设置为auto,但是在绘制datagrid时使用最大列宽。但是,用户应该可以超过此限制来调整大小。这就是为什么我不能使用 MaxColumnWidth
的原因,所以我认为最简单的方法是读取每一列的宽度,如果宽度大于限制,则将其设置为最大值。
<$ c $的 Width
属性的类型c> DataGridColumn 是 DataGridLength
,而不是 double
。
更改源属性的类型:
public DataGridLength宽度
{
得到{return m_width; }
set {m_width = value; OnPropertyChanged( Width); }
}
DataGridLength m_width;
和<$ c的 Mode
$ c>绑定:
< DataGridTextColumn Header = ProductId1 Binding = {绑定路径= Result [1]}
Visibility = {Binding Data.Columns [0] .Visible,Source = {StaticResource proxy}}
Width = {Binding Data.Columns [0] .Width ,Source = {StaticResource proxy},Mode = TwoWay} />
As the columns of a data grid aren't in the visual tree of datagrid I'm m using this approach of Binding Proxy to bind Visibility of a DataGridTextColumn
.
For some reason I would like to understand the same approach does work fine for Visibility
but not for column's Width
property.
Could someone explain this different behavior to me?
Code sample
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;
}
just to make it easier to reproduce
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>
Just for you to know what my original goal is. I would like to set a width to auto for all columns, but with a "maximum" column width during drawing of datagrid. However, user should be possible to resize over this limit. That's why i can't use MaxColumnWidth
So I thought easiest way to realize this would be to read width for every column and set it to "maximum" value if it's bigger than limit.
The type of the Width
property of a DataGridColumn
is DataGridLength
and not double
.
Change type of your source property:
public DataGridLength Width
{
get { return m_width; }
set { m_width = value; OnPropertyChanged("Width"); }
}
DataGridLength m_width;
And the Mode
of the Binding
:
<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}" />
这篇关于Datagridcolumn:通过BindingProxy的绑定可见性和宽度显示不同的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!