如何将用户控件属性绑定到其他属性?

时间:2015-05-31 16:52:12

标签: c# wpf user-controls

我有以下用户控件:

Xaml:

<UserControl x:Class="ScreenRecorder.TimePicker"
         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" 
         mc:Ignorable="d" Height="27" Width="176">
<Grid>
    <StackPanel Orientation="Horizontal">
        <TextBox  Width="150" Height="25" Text="{Binding Time}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <StackPanel Orientation="Vertical">
            <Button Width="25" Height="12.5" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnKeyUp_Clicked">
                <Image Source="up.png" Height="10" Width="10" VerticalAlignment="Top"/>
            </Button>
            <Button Width="25" Height="12.5" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnKeyDown_Clicked">
                <Image Source="down.png" Height="10" Width="10" VerticalAlignment="Top"/>
            </Button>
        </StackPanel>
    </StackPanel>
</Grid>

守则:

 public partial class TimePicker : UserControl, INotifyPropertyChanged
{
    public TimePicker()
    {
        InitializeComponent();
        this.DataContext = this;
        //Time = m_time;
    }

    public static DependencyProperty TimeProperty = DependencyProperty.Register(
        "Time", typeof(string), typeof(TimePicker));

    //private string m_time = DateTime.Now.ToString();
    public string Time
    {
        get { return (string)GetValue(TimeProperty); }
        set
        {
            SetValue(TimeProperty, value);
            NotifyPropertyChanged("Time");
        }
    }

    private void btnKeyUp_Clicked(object sender, RoutedEventArgs e)
    {
        DateTime curTime = Convert.ToDateTime(Time);
        curTime += new TimeSpan(0, 0, 1);
        Time = curTime.ToString();
    }

    private void btnKeyDown_Clicked(object sender, RoutedEventArgs e)
    {
        DateTime curTime = Convert.ToDateTime(Time);
        curTime -= new TimeSpan(0, 0, 1);
        Time = curTime.ToString();
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

我还有另一个使用此用户控件的用户控件,如下所示:

        <StackPanel>
            <Label Content="Begin Record Time" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5"/>
            <local:TimePicker Time="{Binding StartRecordTime}"/>
        </StackPanel>

StartRecordTime如下所示:

public string StartRecordTime
    {
        get { return m_startRecord; }
        set
        {
            m_startRecord = value;
            NotifyPropertyChanged("StartRecordTime");
        }
    }

我想根据时间属性更改StartRecordTime,反之亦然,但只有Time属性正在更改。

谢谢。

2 个答案:

答案 0 :(得分:1)

试试这个:

<local:TimePicker Time="{Binding Path=StartRecordTime, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

答案 1 :(得分:0)

您的绑定无效,因为您已将DataContext的{​​{1}}设置为TimePicker。您会在“输出”窗口中发现绑定错误:

  

BindingExpression路径错误:'object'''TimePicker'(Name ='')'上找不到'StartRecordTime'属性。 BindingExpression:路径= StartRecordTime; DataItem ='TimePicker'(Name =''); target元素是'TimePicker'(Name =''); target属性是'Time'(类型'String')

我建议您从TimePicker构造函数中删除DataContext = this并通过元素名称将网格TimePicker设置为DataContext,以获得更加“理智”的体验。将名称属性添加到TimePicker元素:

UserControl

并设置<UserControl x:Name="Root" ... 的{​​{1}}:

DataContext

这将由所有子元素继承。您还需要明确地将绑定更改为Grid

<Grid DataContext="{Binding ElementName=Root}">

或者将此设置为TwoWay注册中的默认值:

<local:TimePicker Time="{Binding Path=StartRecordTime, Mode=TwoWay}" />

我还注意到DependencyProperty没有理由实施public static readonly DependencyProperty TimeProperty = DependencyProperty.Register( "Time", typeof(string), typeof(TimePicker), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 。我建议你删除它。