【问题标题】:How do I databind a ColumnDefinition's Width or RowDefinition's Height?如何对 ColumnDefinitions Width 或 Row Definition Height 进行数据绑定?
【发布时间】:2010-09-13 22:58:59
【问题描述】:

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

注意:我将这个问题作为参考问题发布,因为谷歌让我失望了,我不得不自己解决这个问题。我自己的答案。

【问题讨论】:

    标签: wpf data-binding grid column-width row-height


    【解决方案1】:

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

    【讨论】:

    • 真的很棒。 String Properties 是解决此问题的最佳 MVVM 模式。
    【解决方案2】:

    如下创建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;
        }
    }
    

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

    <UserControl.Resources>
        <local:GridLengthConverter x:Key="gridLengthConverter" />
    </UserControl.Resources>
    ...
    <ColumnDefinition Width="{Binding Path=LeftPanelWidth, 
                                      Mode=TwoWay,
                                      Converter={StaticResource gridLengthConverter}}" />
    

    【讨论】:

    • 如果您寻求非常相似的问题的解决方案,您可以在这里找到:stackoverflow.com/questions/7660967/…
    • Wpf 已经有一个 GridLengthConverter 类。可以按原样使用吗?
    • @heltonbiker 不幸的是,GridLengthConverter 实现的是 ITypeConverter 而不是 IValueConverter,因此不能用作 WPF 绑定转换。
    【解决方案3】:

    另一种可能性,因为您提出了在GridLengthint 之间进行转换,所以创建一个IValueConverter 并在绑定到Width 时使用它。 IValueConverters 也处理双向绑定,因为它们同时具有 ConvertTo()ConvertBack() 方法。

    【讨论】:

      【解决方案4】:

      我发现了一些陷阱:

      1. 虽然它在 XAML 中可能看起来像双精度,但 *Definition 的高度或宽度的实际值是一个“GridLength”结构。
      2. GridLength 的所有属性都是只读的,每次更改时都必须创建一个新的。
      3. 与 WPF 中的所有其他属性不同,Width 和 Height 不会将其数据绑定模式默认为“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");
          }
      }
      

      还有 XAML:

      <Grid.RowDefinitions>
          <RowDefinition Height="*" MinHeight="100" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="{Binding Path=HorizontalInputRegionSize,Mode=TwoWay}" MinHeight="50" />
      </Grid.RowDefinitions>
      

      【讨论】:

      • GridLength 特定于 WPF,因此不属于 ViewModel 层。
      • 我认为“ViewModel 中没有 WPF”的信念是错误的,因为 WPF 有很多关于 MVVM 模式的构造,例如数据绑定本身。相反,您可以说“GridLength 特定于 VIEW”(除非它是域问题的一部分,例如在数据可视化应用程序中,其目的是布局和显示事物)。但肯定是有争议的......
      • @heltonbiker “GridLength 特定于 VIEW”更准确。除非您的业务逻辑完全或部分与 UI 布局(设计)有关
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      相关资源
      最近更新 更多