Как определить свойство зависимостей в пользовательском элементе управления, который просто заполняет значение одного из его дочерних элементов? - PullRequest
3 голосов
/ 27 ноября 2011

Я создаю пользовательский элемент управления ToggleSwitchItem, который содержит ToggleSwitch и TextBlock. Я определил свойство зависимостей под названием IsChecked, которое я просто хочу использовать для предоставления свойства IsChecked частного дочернего элемента ToggleSwitch.

Но привязка данных не работает ... При загрузке просто остается значение по умолчанию.

Чего мне не хватает?

Код:

public static readonly DependencyProperty IsCheckedProperty =
    DependencyProperty.Register(
        "IsChecked",
        typeof(bool),
        typeof(ToggleSwitchItem),
        new PropertyMetadata(new PropertyChangedCallback
          (OnIsCheckedChanged)));

public bool IsChecked
{
  get
  {
    return (bool)GetValue(IsCheckedProperty);
  }
  set
  {
    SetValue(IsCheckedProperty, value);
  }
}

private static void OnIsCheckedChanged(DependencyObject d,
  DependencyPropertyChangedEventArgs e)
{
  ToggleSwitchItem item = (ToggleSwitchItem)d;
  bool newValue = (bool)e.NewValue;
  item.m_switch.IsChecked = newValue;
}

для привязки данных, я использую следующее:

<phone:PhoneApplicationPage.Resources>
    <myApp:SharedPreferences x:Key="appSettings"/>
</phone:PhoneApplicationPage.Resources>

IsChecked="{Binding Source={StaticResource appSettings}, 
    Path=SomeProperty, Mode=TwoWay}" 

Класс SharedPreferences работает нормально, так как он без проблем работает, когда привязан к простому ванильному свойству IsChecked ToggleSwitch точно так же, как указано выше.

Спасибо!


РЕШЕНИЕ (с помощью Энтони):

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

Binding binding = new Binding();
binding.Source = this;
binding.Path = new PropertyPath("IsChecked");
binding.Mode = BindingMode.TwoWay;
m_switch.SetBinding(ToggleSwitch.IsCheckedProperty, binding);

И я удаляю обратный вызов, так как он мне больше не нужен:

public static readonly DependencyProperty IsCheckedProperty =
    DependencyProperty.Register(
        "IsChecked",
        typeof(bool),
        typeof(ToggleSwitchItem),
        null);

public bool IsChecked
{
  get
  {
    return (bool)GetValue(IsCheckedProperty);
  }
  set
  {
    SetValue(IsCheckedProperty, value);
  }
}

Ответы [ 3 ]

2 голосов
/ 27 ноября 2011

Я не совсем понимаю, что на самом деле не так с кодом, который вы показываете до сих пор, за исключением того, что вы не показали, как пользователь переключил бы переключатель на самом деле, чтобы изменить свойство IsChecked.

Вы пытались использовать привязку внутри UserControl:

<ToggleButton IsChecked="{Binding Parent.IsChecked, ElementName=LayoutRoot, Mode=TwoWay}" />

При таком подходе обратный вызов OnPropertyChanged вам не нужен.

1 голос
/ 27 ноября 2011

Проверьте DataContext вашего элемента управления. Это означает 2 вещи: все экземпляры вашего элемента управления должны иметь право DataContext для работы -ok-, а также вам не следует «ломать» этот DataContext при определении элемента управления (на уровне класса).Если, когда вы определяете свой элемент управления, вы устанавливаете DataContext на «this» / Me в коде или на «Self» в xaml, он теперь ссылается только на себя и забывает о DataContext, в котором он находится, когда вы создаете его в своем приложении- Привязка не удалась.

Если вам нужно обратиться к свойствам вашего элемента управления в вашем элементе управления Xaml, используйте привязку с findAncestor / AncestorType = ToggleSwitchItem Или назовите свой элемент управления в Xaml и выполните привязку с его ElementName.

0 голосов
/ 27 ноября 2011

Может быть, это может помочь

public bool IsChecked
    {
        get { return GetValue(IsCheckedProperty) is bool ? (bool) GetValue(IsCheckedProperty) : false; }
        set
        {
            SetValue(IsCheckedProperty, value);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...