【问题标题】:Binding a custom dependency property to the Width of a control将自定义依赖属性绑定到控件的宽度
【发布时间】:2011-05-08 13:51:15
【问题描述】:

我有一个包含以下元素的用户控件:

        <Border x:Name="border" BorderThickness="1">
            <StackPanel Orientation="Horizontal">
                <CheckBox Margin="5"></CheckBox>
                <TextBox Width="100" Margin="5"/>
            </StackPanel>
        </Border>

在这个用户控件后面的代码中,我有一个自定义依赖属性:

        public static readonly DependencyProperty BorderWidthProperty = DependencyProperty.Register("BorderWidth", typeof(int), typeof(TestControl));
        public int BorderWidth
        {
            get { return (int)base.GetValue(BorderWidthProperty); }
            set { base.SetValue(BorderWidthProperty, value); }
        }

我想要做的是让 BorderWidth 属性始终等于边框控件的宽度。

我尝试添加以下绑定,认为 OneWayToSource 是我需要的,其中 myControl 是包含边框的用户控件的名称:

<UserControl x:Class="Sandbox.TestControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             x:Name="myControl">

<Border x:Name="border" Width="{Binding ElementName=myControl, Path=BorderWidth, Mode=OneWayToSource}">

但我得到以下异常:

System.Windows.Data Error: 7 : ConvertBack cannot convert value 'NaN' (type 'Double'). BindingExpression:Path=BorderWidth; DataItem='TestControl' (Name='myControl'); target element is 'Border' (Name='border'); target property is 'Width' (type 'Double') OverflowException:'System.OverflowException: Value was either too large or too small for an Int32.
   at System.Convert.ToInt32(Double value)
   at System.Double.System.IConvertible.ToInt32(IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
   at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'

我想要做的是让布局系统像往常一样控制边框的宽度,但始终让 BorderWidth 属性等于边框宽度。在尝试更新 BorderWidth 时,似乎没有定义边框元素的宽度。

另外,BorderWidth 属性是否必须是依赖属性才能使其工作?

谢谢。

【问题讨论】:

  • 把int类型改成Double看看
  • 该死,我不知道我是怎么错过的。我进行了更改,但是当边框的宽度发生变化时,BorderWidth 似乎没有随边框宽度更新。

标签: wpf wpf-controls binding


【解决方案1】:

您应该使用FrameworkElement.ActualWidth 属性。

编辑:请参阅下面的评论。这种方法行不通。

【讨论】:

  • 我正要发帖 :) 好电话 (+1)。
  • 我应该在哪里使用 ActualWidth?如果我尝试在 xaml 中将 Width 更改为 ActualWidth,我会收到一条错误消息,指出“'ActualWidth' 属性是只读的,无法从标记中设置。” (虽然我认为使用 OneWayToSource 只是在读取 ActualWidth)。
【解决方案2】:

我最终改变了我的方法。我向我的用户控件添加了一个属性,该属性在边框大小发生变化时更新(监听边框的 SizeChanged 事件)。用户控件实现了 INotifyPropertyChanged,任何对 BorderWidth 感兴趣的人现在总能取回边框元素的 ActualWidth:

        double _borderWidth;
        public double BorderWidth
        {
            get
            {
                return _borderWidth;
            }
            set
            {
                _borderWidth= value;
                this.OnPropertyChanged("BorderWidth");
            }
        }

        private void Border_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
        {
            BorderWidth = border.ActualWidth;
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 2012-08-07
    • 2021-08-17
    • 2011-03-24
    • 1970-01-01
    相关资源
    最近更新 更多