首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >绑定到ColumnDefinition的宽度

绑定到ColumnDefinition的宽度
EN

Stack Overflow用户
提问于 2011-09-05 13:37:10
回答 4查看 10.2K关注 0票数 5

我需要一些用于用户输入的表格。因此,我创建了一个具有定义的列和行的网格。这个表不是用来显示数据的,它的目的只是用来构造输入。

为了结构化所有元素,如文本框等,我定义了所有列的宽度。将有几个网格在堆叠面板中对齐。

XAML中的列定义如下:

代码语言:javascript
复制
<Grid.ColumnDefinitions>
  <ColumnDefinition x:Name="widthLoopID" Width="55" />
</Grid.ColumnDefinition>

我从其他网格中引用了它,比如:

代码语言:javascript
复制
<Grid.ColumnDefinitions>
  <ColumnDefinition Width="{Binding ElementName=widthLoopID, Path=Width}" />
</GridColumnDefinition>

这样做效果很好。

现在是困难的部分。我如何在代码隐藏中做到这一点?

我尝试了以下几种方法:

代码语言:javascript
复制
// define columns
ColumnDefinition loopIdColumn = new ColumnDefinition();
// setup databinding for columns
Binding loopIdBinding = new Binding();
// set binding for width
loopIdBinding.ElementName = "widthLoopID";
loopIdBinding.Path = new PropertyPath("Width");
loopIdColumn.SetBinding(Grid.WidthProperty, loopIdBinding);
// add definition of column
loopGrid.ColumnDefinitions.Add(loopIdColumn);

但在执行时,我会得到以下错误

代码语言:javascript
复制
System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Windows.GridLength' and 'System.Double'. Consider using Converter property of Binding. BindingExpression:Path=Width; DataItem='ColumnDefinition' (HashCode=37457626); target element is 'ColumnDefinition' (HashCode=7871588); target property is 'Width' (type 'Double')

System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='55' BindingExpression:Path=Width; DataItem='ColumnDefinition' (HashCode=37457626); target element is 'ColumnDefinition' (HashCode=7871588); target property is 'Width' (type 'Double')

所以我需要转换"Width",但是我该怎么做呢?为什么它不能像在XAML中那样由默认的转换器执行呢?

我是WPF的新手,可能不会理解所有的概念,所以请给我一个提示。

先谢谢你,班尼

编辑:

我尝试了第一个答案的暗示。它不起作用,因为GridLengthConverter不是来自IValueConverter类型。

所以我写了一个DoubleToGridLengthConverter,它将GridLength转换为Double,反之亦然。

现在,值得到了转换,但结果与代码在XAML中执行的结果不同。我有一种感觉,从代码背后看,它根本不起作用。真的很奇怪。

下面是转换器的代码:

代码语言:javascript
复制
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Globalization;
using System.Diagnostics;

namespace editor
{
   [ValueConversion(typeof(Double), typeof(GridLength))]
   class DoubleToGridLengthConverter : IValueConverter
   {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           // check whether a value is given
           if (value != null)
           {
              Debug.WriteLine("value is: " + value + " type: " + value.GetType());
              return (Double)((GridLength)(value)).Value;
           }
           else
           {
               throw new ValueUnavailableException();
           }
       }

       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           // check whether a value is given
           if (value != null)
           {
               return new GridLength((Double)value);
           }
           else
           {
               throw new ValueUnavailableException();
           }
        }
    }
}

有什么进一步的提示吗?我可以想象,其他人已经有了这个问题。

再次感谢本尼

EN

回答 4

Stack Overflow用户

发布于 2011-09-05 13:46:06

你已经非常接近了,错误是一个很大的提示。您需要使用GridLengthConverter将原始类型(System.Double)转换为GridLength类型(即定义列宽的类型)。

试试这个(未测试):

代码语言:javascript
复制
loopIdBinding.Converter = new System.Windows.GridLengthConverter();

实际上,这应该是您要做的全部工作。这应该会告诉绑定通过转换器运行值,以获得所需的类型。

编辑

所以,是的,GridLengthConverter不是IValueConverter,所以你不能这样做。相反,您需要创建一个实现IValueConverter的新类,如下所示:

代码语言:javascript
复制
public class GridLengthValueConverter : IValueConverter
{
    GridLengthConverter _converter = new GridLengthConverter();

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return _converter.ConvertFrom(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return _converter.ConvertTo(value, targetType);
    }
}

..。然后分配一个新的实例作为您的转换器:

代码语言:javascript
复制
loopIdBinding.Converter = new System.Windows.GridLengthConverter();

同样,这是未经测试的。让我知道进展如何。

票数 2
EN

Stack Overflow用户

发布于 2011-09-06 12:31:15

我想我误解了问题,我没有意识到你在两个网格之间绑定。然而,我已经留下了我之前的答案,因为它可能是相关的。如果您经常需要在代码中添加列,这将是值得考虑的,您正在做一些错误的事情。每种情况都是不同的:-)

无论如何,你的问题的答案是你不需要转换器(‘ta converter )。您刚刚在该行中绑定了错误的属性

代码语言:javascript
复制
loopIdColumn.SetBinding(Grid.WidthProperty, loopIdBinding);

只需将其更改为

代码语言:javascript
复制
loopIdColumn.SetBinding(ColumnDefinition.WidthProperty, loopIdBinding);

一切都运行得很好。

票数 1
EN

Stack Overflow用户

发布于 2012-01-04 23:35:47

如果您所需要做的就是在不同的网格之间同步(共享)列大小,那么您是否已经签出了ColumnDefinition上的SharedSizeGroup属性?听起来这可能会让这件事变得更容易一些。

SharedSizeGroup Property MSDN

来自MSDN链接的代码示例:

代码语言:javascript
复制
<StackPanel>
<Grid ShowGridLines="True" Margin="0,0,10,0">
  <Grid.ColumnDefinitions>
    <ColumnDefinition SharedSizeGroup="FirstColumn"/>
    <ColumnDefinition SharedSizeGroup="SecondColumn"/>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" SharedSizeGroup="FirstRow"/>
  </Grid.RowDefinitions>

    <Rectangle Fill="Silver" Grid.Column="0" Grid.Row="0" Width="200" Height="100"/>
    <Rectangle Fill="Blue" Grid.Column="1" Grid.Row="0" Width="150" Height="100"/>

    <TextBlock Grid.Column="0" Grid.Row="0" FontWeight="Bold">First Column</TextBlock>
    <TextBlock Grid.Column="1" Grid.Row="0" FontWeight="Bold">Second Column</TextBlock>
</Grid>

<Grid ShowGridLines="True">
  <Grid.ColumnDefinitions>
    <ColumnDefinition SharedSizeGroup="FirstColumn"/>
    <ColumnDefinition SharedSizeGroup="SecondColumn"/>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>        
    <RowDefinition Height="Auto" SharedSizeGroup="FirstRow"/>
  </Grid.RowDefinitions>

    <Rectangle Fill="Silver" Grid.Column="0" Grid.Row="0"/>
    <Rectangle Fill="Blue" Grid.Column="1" Grid.Row="0"/>

    <TextBlock Grid.Column="0" Grid.Row="0" FontWeight="Bold">First Column</TextBlock>
    <TextBlock Grid.Column="1" Grid.Row="0" FontWeight="Bold">Second Column</TextBlock>
</Grid>
</StackPanel>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7304203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档