2017-10-17 22 views
0

Comme les colonnes d'une grille de données ne sont pas dans l'arborescence visuelle de la grille de données, j'utilise cette approche de Binding Proxy pour lier la visibilité d'un DataGridTextColumn.Datagridcolumn: visibilité de liaison et largeur via BindingProxy montrent un comportement différent

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

Pour une raison quelconque, je voudrais comprendre la même approche ne fonctionne bien pour Visibility mais pas la propriété de la colonne Width. Quelqu'un pourrait-il m'expliquer ce comportement différent?

Exemple de code

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; 
} 

juste pour le rendre plus facile à reproduire

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> 

Juste pour que vous sachiez quel est mon objectif original. Je voudrais définir une largeur à auto pour toutes les colonnes, mais avec une largeur de colonne "maximale" pendant le dessin de datagrid. Cependant, l'utilisateur devrait pouvoir redimensionner au-delà de cette limite. C'est pourquoi je ne peux pas utiliser MaxColumnWidth J'ai donc pensé que la façon la plus simple de réaliser ceci serait de lire la largeur de chaque colonne et de la mettre à la valeur "maximum" si elle est plus grande que la limite.

Répondre

1

Le type de la propriété Width d'un DataGridColumn est DataGridLength et non double.

Changer le type de votre propriété source:

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

DataGridLength m_width; 

Et le Mode du 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}" /> 
+0

fonctionne parfaitement. Merci beaucoup. Pourriez-vous ajouter ceci à votre réponse ici aussi? Semble être le même problème https://stackoverflow.com/a/42832215/5381620. Je ne peux pas encore ajouter un commentaire :-) – pedrito