Wpf 使用IValueConverter将列宽度绑定到DependencyProperty

Wpf 使用IValueConverter将列宽度绑定到DependencyProperty,wpf,binding,width,ivalueconverter,Wpf,Binding,Width,Ivalueconverter,我试图在网格元素变量中设置列的宽度。为此,我有一个dependencProperty“ItemWidth”,并将按钮的Width元素绑定到此DP。由于双向绑定,我需要一个将double转换为DataGridLength的转换器 My MainWindow.xaml如下所示: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presenta

我试图在网格元素变量中设置列的宽度。为此,我有一个dependencProperty“ItemWidth”,并将按钮的Width元素绑定到此DP。由于双向绑定,我需要一个将double转换为DataGridLength的转换器

My MainWindow.xaml如下所示:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:utils="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Resources>
        <utils:ColumnWidthConverter x:Key="columnWidthConverter"/>
    </Grid.Resources>
    <Button Grid.Row="0" Grid.Column="0" Width="{Binding Path=ItemWidth, Mode=TwoWay, Converter={StaticResource columnWidthConverter}}" Click="Shorter_Click">shorter</Button>
    <Button Grid.Row="0" Grid.Column="1" Width="{Binding Path=ItemWidth, Mode=TwoWay, Converter={StaticResource columnWidthConverter}}" Click="Longer_Click">longer</Button>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public double ItemWidth
        {
            get { return (double)GetValue(ItemWidthProperty); }
            set { SetValue(ItemWidthProperty, value); }
        }

        public static readonly DependencyProperty ItemWidthProperty =
        DependencyProperty.Register("ItemWidth", typeof(double), typeof(MainWindow), new UIPropertyMetadata(0.0));

        private void Shorter_Click(object sender, RoutedEventArgs e)
        {
            this.ItemWidth -= 100;
        }

        private void Longer_Click(object sender, RoutedEventArgs e)
        {
            this.ItemWidth += 100;
        }
    }
}
MainWindow.xaml.cs如下所示:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:utils="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Resources>
        <utils:ColumnWidthConverter x:Key="columnWidthConverter"/>
    </Grid.Resources>
    <Button Grid.Row="0" Grid.Column="0" Width="{Binding Path=ItemWidth, Mode=TwoWay, Converter={StaticResource columnWidthConverter}}" Click="Shorter_Click">shorter</Button>
    <Button Grid.Row="0" Grid.Column="1" Width="{Binding Path=ItemWidth, Mode=TwoWay, Converter={StaticResource columnWidthConverter}}" Click="Longer_Click">longer</Button>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public double ItemWidth
        {
            get { return (double)GetValue(ItemWidthProperty); }
            set { SetValue(ItemWidthProperty, value); }
        }

        public static readonly DependencyProperty ItemWidthProperty =
        DependencyProperty.Register("ItemWidth", typeof(double), typeof(MainWindow), new UIPropertyMetadata(0.0));

        private void Shorter_Click(object sender, RoutedEventArgs e)
        {
            this.ItemWidth -= 100;
        }

        private void Longer_Click(object sender, RoutedEventArgs e)
        {
            this.ItemWidth += 100;
        }
    }
}

因此,当我单击其中一个按钮时,按钮的宽度应该改变。但事实并非如此。您能告诉我这是为什么以及某种解决方案吗?

您在绑定中没有设置任何源,因此它是相对于的,如果您添加了它,它似乎没有在任何地方设置。e、 g

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" ...

我将以下内容用于GridSplitter

public class DoubleToGridLengthConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        double i = (double)value;

        GridLength result = new GridLength(i);

        return result;

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {

        GridLength g = (GridLength)value;

        return (double)g.Value;

    }

}
xaml


您好,您是否有意在转换函数中编写此代码?返回新的DataGridLength(100);你应该用这个吗?返回结果;抱歉,这是为了调试目的。返回结果也不起作用。ItemWidth会改变,但按钮的大小不会改变。你说的大小是什么意思?是高度还是宽度?两者都有。但重要的是:宽度不会改变..可视化效果保持不变.非常感谢您提供的信息!不幸的是,DataContext的设置没有解决这个问题。@Hauke:如果有绑定错误,请告诉我们。还有,你为什么要绑这个按钮。宽度?查看我添加的nate…这只是一个示例应用程序。实际上,我需要手动实现一个GridSplitter。为此,我需要更改宽度。没有绑定错误。这就是我不明白的。据我所知,代码应该可以正常工作。在该公司的项目中,网格的结构非常复杂,因此我必须使用button(或者Border)元素的宽度属性。正因为如此,我需要转换器。。没有其他错误。@Hauke:目前您正在将一个
double
绑定到一个
double
,您不需要转换器。您是否在转换器中设置了断点,它是否被调用?是的,它被调用。当我尝试在不使用转换器的情况下解决此问题时,它会说:“无法创建默认转换器来执行“System.Double”和“Microsoft.Windows.Controls.DataGridLength”类型之间的“双向”转换。”但实际上我只需要方法Convert(而不是ConvertBack)。结果对象是DataGridLength,因此不会留下任何错误。