2015-12-20 2 views
1

Я делаю отображение времени/часов в качестве пользовательского элемента управления (ClockControl) на странице, фактическая модель времени управляется из объекта DateTime из другого класса (ClockTime). У меня 2 TextBlocks на ClockControl:Вопросы о кодах в установщике DependencyProperty в пользовательском элементе управления

  1. TextBlock «Second_update_by_binding» привязан к свойству зависимостей «Second_binded», который в свою очередь связан с модели ClockTime «Второй».

  2. TextBlock «Second_update_by_manipulating» обновляется, манипулируя значение модели ClockTime «Second» так, что он добавляет «0» на фронте, если «Второй» только одна цифра (или менее 10)

Мне удалось добиться того, чего я хочу, независимо от его наилучшего подхода. Однако я столкнулся с несколькими вопросами, которые я не совсем понимаю, почему они происходят. В частности, это логика кода внутри геттера/сеттера в свойстве зависимости в пользовательском элементе Clock, с которым я больше всего смущен.

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"); в настройщике свойства Second_binded dependency в ClockControl никогда не вызывается, когда обновляется «Second» в модели ClockTime.

  2. Код Debug.WriteLine ("in Second_manipulated"); в настройщике свойства Second_manipulated dependency в ClockControl вызывается и код Value_1.Text = (Convert.ToInt32 (значение) < 10)? «0» + значение: значение; выполнен для изменения текста на ClockControl, но он работает только после добавления другого DispatchTimer с MainPage.cs, чтобы заставить код useControl.Second_manipulated = clock.Second.ToString();, чтобы обновить время. Почему я должен сделать это таким образом, чтобы обновить Second_manipulated, хотя я уже установил Second_manipulated привязан к Second в MainPage.xaml?

Любые идеи и комментарии для ознакомления с моими знаниями на 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 полезен! так что не имеет значения, что вы положили в сеттер и геттер для привязки? –

+0

Не для привязки нет, только когда он вызывается из кода. – Bart

Смежные вопросы