2015-12-20 166 views
1

我在页面上显示时间/时钟作为用户控件(ClockControl),实际时间模型是从另一个类的DateTime对象驱动的( ClockTime)。我对ClockControl 2周的TextBlocks:关于用户控件中DependencyProperty的setter中代码的问题

  1. 文字块“Second_update_by_binding”势必又被绑定到模型ClockTime“二”依赖属性“Second_binded”。

  2. 正文块“Second_update_by_manipulating”由操纵模型ClockTime“第二”,使得它增加了的值来更新“0”,在前面,如果“第二”仅是1位(或小于10)

我设法实现我想要的,不管它是否是最好的方法。但是,我遇到了几个我不太明白为什么会发生的问题。具体来说,它是时钟用户控件中依赖项属性中getter/setter内部代码的逻辑,这是我最困惑的。

MainPage.xaml中:

<Page x:Class="App1.MainPage" ..."> 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <local:ClockControl x:Name="useControl" 
       Second_binded="{Binding Second}" 
       Second_manipulated="{Binding Second}" /> 
    </Grid> 
</Page> 

MainPage.cs:

public sealed partial class MainPage : Page 
{ 
    ClockTime clock; 
    DispatcherTimer Timer; 

    public MainPage() 
    { 
     clock = new ClockTime(); 
     this.InitializeComponent(); 
     this.DataContext = clock; 
      // I am adding this DispatchTimer to force the update of the text 
      // 'Second_update_by_manipulating' on the ClockControl since the 
      // Binding of Second_manipulated doesnt work 
     Timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) }; 
     Timer.Tick += Timer_Tick; 
     Timer.Start(); 
    } 

    private void Timer_Tick(object sender, object e) 
    { 
     useControl.Second_manipulated = clock.Second.ToString(); 
    } 
} 

ClockTime型号:

class ClockTime : INotifyPropertyChanged 
{ 
    public ClockTime() 
    { 
     var Timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) }; 
     Timer.Tick += Timer_Tick; 
     Timer.Start(); 
    } 

    private void Timer_Tick(object sender, object e) 
    { 
     Second = DateTime.Now.Second; 
    } 

    //=================================================== 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
    //=================================================== 
    private int _second; 
    public int Second 
    { 
     get { return this._second; } 
     set 
     { 
      if (value != this._second) 
      { 
       this._second = value; 
       NotifyPropertyChanged("Second"); 
      } 
     } 
    } 
} 

ClockControl.xaml:

<UserControl x:Class="App1.ClockControl" ...> 
    <Grid> 
     <StackPanel> 
      <TextBlock x:Name="Second_update_by_manipulating" /> 
      <TextBlock x:Name="Second_update_by_binding" Text="{Binding Second_binded}" /> 
     </StackPanel> 
    </Grid> 
</UserControl> 

ClockControl.cs:

public sealed partial class ClockControl : UserControl 
{ 
    public ClockControl() 
    { 
     this.InitializeComponent(); 
     (this.Content as FrameworkElement).DataContext = this; 
    } 
    //================================== 
    public String Second_binded 
    { 
     get { 
      return (String)GetValue(Second_bindedProperty); 
     } 
     set { 
      Debug.WriteLine(" in Second_binded "); 
      SetValue(Second_bindedProperty, value); 
     } 
    } 
    public static readonly DependencyProperty Second_bindedProperty = 
     DependencyProperty.Register(
     "Second_binded", 
     typeof(string), 
     typeof(ClockControl), 
     new PropertyMetadata("")); 
    //================================== 
    public String Second_manipulated 
    { 
     get 
     { 
      return (String)GetValue(Second_manipulatedProperty); 
     } 
     set 
     { 
      Second_update_by_manipulating.Text = (Convert.ToInt32(value)<10) ? "0"+value : value; 
      Debug.WriteLine(" in Second_manipulated "); 
      SetValue(Second_manipulatedProperty, value); 
     } 
    } 
    public static readonly DependencyProperty Second_manipulatedProperty = 
     DependencyProperty.Register(
     "Second_manipulated", 
     typeof(string), 
     typeof(ClockControl), 
     new PropertyMetadata("")); 
    //================================== 
} 

所以这里是我的问题:

  1. 为什么调试代码的Debug.WriteLine( “在Second_binded”);在模型ClockTime中的'Second'正在更新时,ClockControl中的Second_binded依赖项属性的setter中的永远不会被调用。

  2. 代码Debug.WriteLine(“in Second_manipulated”); ClockControl中的Second_manipulated依赖项属性的setter被调用且代码Value_1.Text =(Convert.ToInt32(value)< 10)? “0”+ value:value;执行以更改ClockControl上的文本,但仅在添加另一个DispatchTimer并使用MainPage.cs强制执行代码后才起作用useControl.Second_manipulated = clock.Second.ToString();更新时间。为什么我必须这样做来更新Second_manipulated,即使我已经在MainPage.xaml中将Second_manipulated绑定为Second了?

任何想法和意见,启发我的知识在C#非常受欢迎。

感谢

+0

@marc_s,谢谢你更新我的文本:-) –

回答

1

如果你想跟踪一个DependencyProperty变化,你必须注册一个PropertyChangedCallback处理。更新绑定的值时,系统不会触发属性设置器。

public static readonly DependencyProperty Second_bindedProperty = 
     DependencyProperty.Register(
     "Second_binded", 
     typeof(string), 
     typeof(ClockControl), 
     new PropertyMetadata("", PropertyChangedCallback)); 

private static void PropertyChangedCallback(DependencyObject dependencyObject, 
      DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) 
{ 
    Debug.WriteLine(" in Second_binded callback"); 
} 

之所以你的二传手被击中的第二个属性是因为你强迫自己将其与useControl.Second_manipulated = clock.Second.ToString();,这是不使用绑定的正确途径。

+0

感谢callBack方法,这很有用!所以它无关紧要你在setter和getter中绑定了什么? –

+0

不适用于绑定否,只有当它从代码调用时。 – Bart

相关问题