2017-10-17 30 views
0

データグリッドの列がDataGridのビジュアルツリーにないため、このバインディングプロキシのアプローチを使用して可視性をバインドするのはDataGridTextColumnです。私は同じアプローチは、列のWidthプロパティにVisibilityのために正常に動作しませんが、理解したいと思いますいくつかの理由Datagridcolumn:BindingProxyによるバインディングの可視性と幅が異なる動作を示します

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

。 誰かが私にこの異なる行動を説明できますか?

コードサンプル

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> 

私の本来の目標が何であるかを知っているだけです。私は、すべての列の幅をautoに設定したいと思いますが、DataGridの描画時には「最大」の列幅を設定します。ただし、この制限を超えてサイズ変更することは可能です。だからこそ私はMaxColumnWidthを使うことができません。だから、これを実現する最も簡単な方法は、すべての列の幅を読み込み、それが限界より大きい場合は "最大"値に設定することです。

答えて

1

DataGridColumnWidthプロパティのタイプはDataGridLengthであり、doubleではありません。あなたのソースプロパティの

変更タイプ:

public DataGridLength Width 
{ 
    get { return m_width; } 
    set { m_width = value; OnPropertyChanged("Width"); } 
} 

DataGridLength m_width; 

そしてBindingMode

<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}" /> 
完璧に動作
+0

。どうもありがとう。ここにあなたの回答にこれを追加できますか?同じ問題と思われるhttps://stackoverflow.com/a/42832215/5381620私はまだコメントを追加していないかもしれません:-) – pedrito

関連する問題