如何对ColumnDefinition的Width或RowDefinition的高度进行数据绑定?

Nid*_*ocu 33 data-binding wpf grid column-width row-height

在WPF的View-Model-ViewModel模式下,我试图为网格控件的各种定义的高度和宽度进行数据绑定,因此我可以在使用GridSplitter后存储用户设置它们的值.但是,正常模式似乎不适用于这些特定属性.

注意:我发布这个作为参考问题,我发布谷歌失败了我,我不得不自己解决这个问题.我自己的答案可以遵循.

Gre*_*som 39

创建IValueConverter如下:

public class GridLengthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        double val = (double)value;
        GridLength gridLength = new GridLength(val);

        return gridLength;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        GridLength val = (GridLength)value;

        return val.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在绑定中使用转换器:

<UserControl.Resources>
    <local:GridLengthConverter x:Key="gridLengthConverter" />
</UserControl.Resources>
...
<ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
                                  Mode=TwoWay,
                                  Converter={StaticResource gridLengthConverter}}" />
Run Code Online (Sandbox Code Playgroud)

  • @heltonbiker不幸的是,GridLengthConverter实现了ITypeConverter而不是IValueConverter,因此不能用作WPF绑定转换. (4认同)
  • Wpf 已经有一个 GridLengthConverter 类。可以按原样使用吗? (2认同)

Nid*_*ocu 20

我发现了很多陷阱:

  1. 尽管在XAML中看起来像是双精度,但*Definition的高度或宽度的实际值是'GridLength'结构.
  2. GridLength的所有属性都是只读的,每次更改时都必须创建一个新属性.
  3. 与WPF中的每个其他属性不同,宽度和高度不会将其数据绑定模式默认为"TwoWay",您必须手动设置它.

因此,我使用了以下代码:

private GridLength myHorizontalInputRegionSize = new GridLength(0, GridUnitType.Auto)
public GridLength HorizontalInputRegionSize
{
    get
    {
        // If not yet set, get the starting value from the DataModel
        if (myHorizontalInputRegionSize.IsAuto)
            myHorizontalInputRegionSize = new GridLength(ConnectionTabDefaultUIOptions.HorizontalInputRegionSize, GridUnitType.Pixel);
        return myHorizontalInputRegionSize;
    }
    set
    {
        myHorizontalInputRegionSize = value;
        if (ConnectionTabDefaultUIOptions.HorizontalInputRegionSize != myHorizontalInputRegionSize.Value)
        {
            // Set the value in the DataModel
            ConnectionTabDefaultUIOptions.HorizontalInputRegionSize = value.Value;
        }
        OnPropertyChanged("HorizontalInputRegionSize");
    }
}
Run Code Online (Sandbox Code Playgroud)

和XAML:

<Grid.RowDefinitions>
    <RowDefinition Height="*" MinHeight="100" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
</Grid.RowDefinitions>
Run Code Online (Sandbox Code Playgroud)

  • GridLength特定于WPF,因此不属于ViewModel层. (9认同)
  • 我认为"在ViewModel中没有WPF"的信念是错误的,因为WPF有很多关于MVVM模式的结构,比如非数据绑定本身.您可以说"GridLength特定于VIEW",而不是(除非它是域问题的一部分,例如在数据可视化应用程序中,其布局和显示事物非常简单).但肯定是有争议的...... (3认同)

小智 7

最简单的解决方案是简单地为这些属性使用字符串设置,以便 WPF 将使用 GridLengthConverter 自动支持它们,而无需任何额外工作。

  • 非常棒。“字符串属性”是解决此问题的最佳 MVVM 模式。 (3认同)