将自定义依赖项属性绑定到控件的宽度

时间:2010-11-11 16:13:59

标签: wpf wpf-controls binding

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

        <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属性是否必须是依赖属性才能使其工作?

感谢。

2 个答案:

答案 0 :(得分:1)

我最终改变了我的做法。我向我的用户控件添加了一个属性,只要边框大小发生更改(听边框的SizeChanged事件),就会更新该属性。用户控件实现了INotifyPropertyChanged,任何对BorderWidth感兴趣的人现在总是会返回border元素的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;
        }

答案 1 :(得分:0)

您应该使用FrameworkElement.ActualWidth属性。

编辑:请参阅下面的评论。这种方法不起作用。