Привязка к DependencyProperty пользовательского элемента управления - PullRequest
1 голос
/ 20 декабря 2011

Я создаю элемент управления TimeInput, как для ввода времени.

<TextBox Text="{Binding Path=Hours}" />
<TextBox IsReadOnly="True"
         Focusable="False"
         Text=":" />
<TextBox Text="{Binding Path=Minutes}" />

и

public int Hours {
  get { return (int)this.GetValue(HoursProperty); }
  set {
    this.SetValue(HoursProperty, value);
    this.OnPropertyChanged("Hours");
  }
}

public static readonly DependencyProperty HoursProperty =
  DependencyProperty.Register("Hours", typeof(int), typeof(UserControl1), new UIPropertyMetadata(0, new PropertyChangedCallback(OnHoursChanged)));

private static void OnHoursChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
  if (obj != null) {
    int newValue = (int)e.NewValue;
  }
}

public int Minutes {
  get { return (int)this.GetValue(MinutesProperty); }
  set {
    this.SetValue(MinutesProperty, value);
    this.OnPropertyChanged("Minutes");
  }
}

// Using a DependencyProperty as the backing store for Minutes.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty MinutesProperty =
  DependencyProperty.Register("Minutes", typeof(int), typeof(UserControl1), new UIPropertyMetadata(0, new PropertyChangedCallback(OnMinutesChanged)));

private static void OnMinutesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
  if (obj != null) {
    int newValue = (int)e.NewValue;
  }
}

public Nullable<TimeSpan> Value {
  get { return (Nullable<TimeSpan>)this.GetValue(ValueProperty); }
  set {
    this.SetValue(ValueProperty, value);
    this.OnPropertyChanged("Value");
  }
}

// Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
  DependencyProperty.Register("Value", typeof(Nullable<TimeSpan>), typeof(UserControl1), new UIPropertyMetadata(null, new PropertyChangedCallback(OnValueChanged)));

private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
  if (obj != null) {
    (obj as UserControl1).UpdateTime(e.NewValue as TimeSpan?);
  }
}

public void UpdateTime(TimeSpan? newTimeSpan) {
  if (newTimeSpan.HasValue) {
    this.Hours = newTimeSpan.Value.Hours;
    this.Minutes = newTimeSpan.Value.Minutes;
  }
}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name) {
  PropertyChangedEventHandler handler = this.PropertyChanged;
  if (handler != null) {
    handler(this, new PropertyChangedEventArgs(name));
  }
}

#endregion

В то время как я использую это на другом UserControl и привязка к свойству. Это не работает и показывает значения.Я использую это так:

<uc:UserControl1 Value="{Binding StartTime}"/>

и

public TimeSpan StartTime
{
  get { return new Types.Time(Item.StartTime).ToTimeSpan(); }
  set { Item.StartTime = new Types.Time(value).ToShort(); NotifyPropertyChanged("StartTime"); }
}

Что Item - это объект, считываемый из базы данных и связывание, а StartTime - это краткая форма hhmm.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2011

Я обновил ваш код, со свойствами зависимостей вам не нужно явно запускать событие изменения свойства.

public partial class UserControl1 : UserControl
{
  public UserControl1() {
    this.InitializeComponent();
  }

  public int Hours {
    get { return (int)this.GetValue(HoursProperty); }
    set { this.SetValue(HoursProperty, value); }
  }

  public static readonly DependencyProperty HoursProperty =
    DependencyProperty.Register("Hours", typeof(int), typeof(UserControl1), new UIPropertyMetadata(0, new PropertyChangedCallback(OnHoursChanged)));

  private static void OnHoursChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
    var uc = obj as UserControl1;
    if (uc != null && e.NewValue != e.OldValue) {
      int newValue = (int)e.NewValue;
      uc.TimeValue = new TimeSpan(newValue, uc.Minutes, 0);
    }
  }

  public int Minutes {
    get { return (int)this.GetValue(MinutesProperty); }
    set { this.SetValue(MinutesProperty, value); }
  }

  // Using a DependencyProperty as the backing store for Minutes.  This enables animation, styling, binding, etc...
  public static readonly DependencyProperty MinutesProperty =
    DependencyProperty.Register("Minutes", typeof(int), typeof(UserControl1), new UIPropertyMetadata(0, new PropertyChangedCallback(OnMinutesChanged)));

  private static void OnMinutesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
    var uc = obj as UserControl1;
    if (uc != null && e.NewValue != e.OldValue) {
      int newValue = (int)e.NewValue;
      uc.TimeValue = new TimeSpan(uc.Hours, newValue, 0);
    }
  }

  public Nullable<TimeSpan> TimeValue {
    get { return (Nullable<TimeSpan>)this.GetValue(ValueProperty); }
    set { this.SetValue(ValueProperty, value); }
  }

  public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register("TimeValue", typeof(Nullable<TimeSpan>), typeof(UserControl1), new UIPropertyMetadata(null, new PropertyChangedCallback(OnValueChanged)));

  private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
    var uc = obj as UserControl1;
    if (uc != null && e.NewValue != e.OldValue) {
      uc.UpdateTime(e.NewValue as TimeSpan?);
    }
  }

  public void UpdateTime(TimeSpan? newTimeSpan) {
    if (newTimeSpan.HasValue) {
      this.Hours = newTimeSpan.Value.Hours;
      this.Minutes = newTimeSpan.Value.Minutes;
    }
  }
}

секунда, я думаю, что вы используете неверное свойство StartTime, используйте его как свойство зависимости тожеили внедрите INotifyPropertyChanged.

{
  // .....
  StartTime = new Types.Time(this.Item.StartTime).ToTimeSpan();
  // .....
}


public static readonly DependencyProperty StartTimeProperty =
  DependencyProperty.Register("StartTime", typeof(TimeSpan?), typeof(Window1), new PropertyMetadata(default(TimeSpan?), new PropertyChangedCallback(OnStartTimePropertyChanged)));

private static void OnStartTimePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) {
  if(e.NewValue != e.OldValue) {
    (dependencyObject as Window1).Item.StartTime = new Types.Time(e.NewValue).ToShort();
  }
}

public TimeSpan? StartTime {
  get { return (TimeSpan?)GetValue(StartTimeProperty); }
  set { SetValue(StartTimeProperty, value); }
}

надеюсь, это поможет

0 голосов
/ 20 декабря 2011

У вас не должно быть никакого другого кода, кроме того, чтобы вызывать GetValue и SetValue внутри getter и setter свойства зависимостей. Но это не может решить вашу проблему. Если вы хотите вызвать некоторый код при изменении значения, сделайте это внутри метода обратного вызова вместо установщика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...