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

发布于 2024-12-29 16:13:24 字数 3528 浏览 4 评论 0原文

我正在尝试使网格元素中的列的宽度可变。为此,我有一个 DependencyProperty“ItemWidth”,并将 Width 元素从 Button 绑定到此 DP。由于 TwoWay-Binding,我需要一个将双精度数转换为 DataGridLength 的转换器。

我的 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>

ColumnWidthConverter.cs 如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;

namespace WpfApplication1
{
    class ColumnWidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return null;
            else
            {
                DataGridLengthConverter cv = new DataGridLengthConverter();
                object result = cv.ConvertFrom(value);
                return result;
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return null;
            else
            {
                DataGridLengthConverter cv = new DataGridLengthConverter();
                return cv.ConvertTo(value, typeof(double));
            }
        }
    }
}

MainWindow.xaml.cs 如下所示:

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;
        }
    }
}

因此,当我单击其中一个按钮时,按钮的宽度应该发生变化。但这并没有发生。你能告诉我这是为什么以及某种解决方案吗?

I am trying to make the width of a column in a Grid element variable. For this I have a DependencyProperty "ItemWidth" and bind the Width-element from the Button to this DP. Because of the TwoWay-Binding, I need a converter that converts doubles to DataGridLength.

My MainWindow.xaml looks like this:

<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>

The ColumnWidthConverter.cs is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows;

namespace WpfApplication1
{
    class ColumnWidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return null;
            else
            {
                DataGridLengthConverter cv = new DataGridLengthConverter();
                object result = cv.ConvertFrom(value);
                return result;
            }

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return null;
            else
            {
                DataGridLengthConverter cv = new DataGridLengthConverter();
                return cv.ConvertTo(value, typeof(double));
            }
        }
    }
}

And the MainWindow.xaml.cs looks like this:

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;
        }
    }
}

So the Width of the Buttons should change when I click one of the Buttons. But this does not happen. Can you tell me why that is and some sort of solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

死开点丶别碍眼 2025-01-05 16:13:24

您在绑定中没有设置源,因此它是相对于 DataContext,您似乎没有在任何地方设置它,如果您添加它应该可以工作。例如,

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

您可能想要(即您绝对应该)查看调试数据绑定(如果您不熟悉的话)。

你还绑定了不需要转换器的属性,实际上转换器可能会在这里引起问题,你不是想绑定ColumnDefinition.Width吗?

You set no source in the binding, hence it is relative to the DataContext, which you do not appear to have set anywhere, if you add it that should work. e.g.

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

You might want to (i.e. you definitely should) look into debugging data bindings if you are not familiar with it.

You also bind properties which have no need for the converter, in fact the converter will probably cause problems here, did you not mean to bind the ColumnDefinition.Width?

很快妥协 2025-01-05 16:13:24

我将以下内容用于我的 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

Width="{Binding Source={x:Static Properties:Settings.Default}, Path=GridSplitter, Mode=TwoWay, Converter={StaticResource GridLengthConverter}}"

i use the following for my 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

Width="{Binding Source={x:Static Properties:Settings.Default}, Path=GridSplitter, Mode=TwoWay, Converter={StaticResource GridLengthConverter}}"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文