数据绑定在简单的UserControl中失败

时间:2012-01-10 12:05:38

标签: c# wpf xaml data-binding user-controls

首先,为所有XAML道歉。我已经尝试了几天来解决这个问题,但我必须遗漏一些东西。摘要问题是我的UserControl依赖项属性在使用时似乎没有在代码隐藏中进行数据绑定。

详细信息:我有以下简单的UserControl(在它自己的dll中),我使用0..59的滑块选择秒,UserControl有一个依赖属性{{ 1}}返回Value,由通过滑块选择的秒数组成:

TimeSpan

使用简单(省略)的xaml:

public partial class TinyTimeSpanControl : UserControl, INotifyPropertyChanged
{
    public TinyTimeSpanControl()
    {
        InitializeComponent();
    }

    private int _seconds;

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public int Seconds
    {
        get { return _seconds; }
        set
        {
            if (_seconds == value)
                return;
            _seconds = value;
            RaisePropertyChanged("Seconds");

            var t = Value;
            Value = new TimeSpan(t.Hours, t.Minutes, _seconds);
        }
    }

    public TimeSpan Value
    {
        get { return (TimeSpan) GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        TinyTimeSpanControl control = obj as TinyTimeSpanControl;
        var newValue = (TimeSpan)e.NewValue;

        control.Seconds = newValue.Seconds;
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
      "Value", typeof(TimeSpan), typeof(TinyTimeSpanControl), new PropertyMetadata(OnValueChanged));
}

控件中的绑定工作正常。

现在当我编译它时,然后将<UserControl x:Class="WpfControlLibrary1.TinyTimeSpanControl" x:Name="root"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Slider Name="SecondsSlider" Width="120" Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" LargeChange="5" SelectionStart="0" SmallChange="1" Value="{Binding Path=Seconds, ElementName=root}" SelectionEnd="59" Maximum="59" /> <Label Name="label1" Grid.Column="1" Content="{Binding ElementName=SecondsSlider, Path=Value}" /> <Label Name="label2" Grid.Column="2" Content="Seconds" /> </Grid> </UserControl> 添加到我的一个窗口(省略):

TinyTimeSpanControl

我的主窗口:

    <Window x:Class="WpfControls.MainWindow"
            xmlns:my="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
            x:Name="root"
            Closing="root_Closing">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="142*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <my:TinyTimeSpanControl Name="tinyTimeSpanControl1"
                                    HorizontalAlignment="Left"
                                    VerticalAlignment="Top"
                                    Value="{Binding ElementName=root,
                                                    Path=TheTime}" />
            <Label Name="label1"
                   Grid.Column="1"
                   Content="{Binding ElementName=tinyTimeSpanControl1,
                                     Path=Value}" />
            <Label Name="label2"
                   Grid.Column="2"
                   Content="{Binding ElementName=root,
                                     Path=TheTime}" />

        </Grid>
    </Window>

数据绑定部分有效:

  • public partial class MainWindow : Window, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } private TimeSpan _theTime = new TimeSpan(0, 0, 33); public TimeSpan TheTime { get { return _theTime; } set { if (_theTime == value) return; _theTime = value; RaisePropertyChanged("TheTime"); } } 最初在我的主窗口后面的代码中设置为tinyTimeSpanControl1属性的值
  • 移动滑块时
  • TheTime更新tinyTimeSpanControl1

但不起作用:

  • 当滑块移动时,label1仍设置为原始版本的label2

TheTime事件中加入断点表明Window_closing未发生变化。

我错过了一些我需要在TheTime中提出的事件吗?

谢谢,并再次为所有xaml道歉(这也是最小的案例)。

1 个答案:

答案 0 :(得分:2)

这是问题所在:

Value = new TimeSpan(t.Hours, t.Minutes, _seconds);

这会清除您在窗口中建立的绑定,只需设置一个值即可。在UserControl代码中,您不应使用SetValue,而应使用SetCurrentValue,这样可以保持对该属性的绑定。

其他一些事情也可能会被关闭,我还没看到......