我需要某种表格供用户输入。所以我创建了一个包含定义的列和行的网格。
这个表不是用来显示数据的,它只是用来构造输入。
要构造所有元素,如文本框等,我定义了所有具有宽度的列。在一个堆栈面板中将有多个网格对齐。
xaml中的列定义如下:

<Grid.ColumnDefinitions>
  <ColumnDefinition x:Name="widthLoopID" Width="55" />
</Grid.ColumnDefinition>

我从其他网格中引用了这一点,比如:
<Grid.ColumnDefinitions>
  <ColumnDefinition Width="{Binding ElementName=widthLoopID, Path=Width}" />
</GridColumnDefinition>

效果很好。
现在是困难的部分。如何在代码隐藏中执行此操作?
我尝试了以下方法:
// 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);

但是当我被执行的时候,我得到了如下的错误
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中的结果不同。我有一种感觉,它根本不工作的代码背后。真奇怪。
这是转换器的代码:
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();
           }
        }
    }
}

还有什么线索吗?我可以想象其他人已经有了这个问题。
再次感谢
本尼

最佳答案

你很接近,这个错误是一个很大的暗示。您需要使用GridLengthConverter将原始类型(System.Double)转换为GridLength类型(即列宽的定义)。
试试这个(未经测试):

loopIdBinding.Converter = new System.Windows.GridLengthConverter();

事实上,这就是你要做的。这应该告诉绑定通过转换器运行该值以获得所需的类型。
编辑
所以是的,GridLengthConverter不是一个IValueConverter所以你不能这样做。相反,您需要创建一个新类来实现如下IValueConverter
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);
    }
}

…然后将此实例的新实例指定为转换器:
loopIdBinding.Converter = new System.Windows.GridLengthConverter();

同样,这是未经测试的。告诉我进展如何。

09-17 01:57