Datagridcolumn:通过BindingProxy的绑定可见性和宽度显示不同的行为 [英] Datagridcolumn: Binding Visibility and Width via BindingProxy show different behavior

查看:373
本文介绍了Datagridcolumn:通过BindingProxy的绑定可见性和宽度显示不同的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于数据网格的列不在数据网格的可视树中,所以我正在使用这种绑定代理方法来绑定 DataGridTextColumn 的可见性。 / p>

> https://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext -is-not-inherited /



出于某种原因,我想了解相同的方法确实对 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.

https://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

For some reason I would like to understand the same approach does work fine for Visibility but not for column's Widthproperty. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆