Столбец данных: видимость и ширина привязки через BindingProxy показывают различное поведение

Поскольку столбцы сетки данных не находятся в визуальном дереве сетки данных, я использую этот подход Binding Proxy для привязки видимости DataGridTextColumn,

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
{
    #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>

Просто для того, чтобы вы знали, какова моя первоначальная цель. Я хотел бы установить ширину в авто для всех столбцов, но с "максимальной" шириной столбца при рисовании сетки данных. Тем не менее, пользователь должен иметь возможность изменить размер выше этого предела. Вот почему я не могу использовать MaxColumnWidth Поэтому я подумал, что самый простой способ понять это - прочитать ширину для каждого столбца и установить для нее "максимальное" значение, если оно больше предела.

1 ответ

Решение

Тип Width свойство DataGridColumn является DataGridLength и не double,

Измените тип вашего исходного свойства:

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

DataGridLength m_width;

И Mode из 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}" />
Другие вопросы по тегам