Установить ResourceDictionary DataContext из кода позади - PullRequest
3 голосов
/ 28 сентября 2011

Я пытаюсь установить ResourceDictionary DataContext из кода моего словаря ресурсов.

У меня есть шаблон данных, который использует свой собственный стиль (словарь ресурсов), стиль содержит флажок ссвой собственный стиль:

<Style x:Key="CheckBoxStyle" TargetType="CheckBox">
    <EventSetter Event="CheckBox.Checked" Handler="CheckBox_Checked"/>
    <EventSetter Event="CheckBox.Unchecked" Handler="CheckBox_Unchecked"/>        
</Style>

В событии CheckBox_Checked я хочу сослаться на родительскую модель представления словаря (пользовательский элемент управления), чтобы выполнить функцию, но поскольку у словарей ресурсов нет свойства DataContext, устанавливающего свойствоDataContext изнутри управляющего события, например:

    private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {  
      MyViewModel viewModel = (MyViewModel)DataContext;
    }

не работает (конечно).

Я думаю, мне нужно получить дескриптор Ancestor (пользователь словаря ресурсов)Контроль), но не знаю, как это сделать - или может быть другой способ ..

Спасибо

Джо

1 Ответ

7 голосов
/ 28 сентября 2011

Как говорится в комментарии @ dowhilefor, словари ресурсов - это просто набор ресурсов, поэтому им не нужен DataContext. Однако вы можете добавить файл с выделенным кодом в ResourceDictionary, который может быть тем, что вы ищете.

Создайте новый класс в том же каталоге, что и ваш ResourceDictionary, и назовите его ResourceDictionaryName.xaml.cs. Он станет файлом кода для вашего ResourceDictionary.

Откройте новый файл .cs и убедитесь, что имеется следующее (не могу вспомнить, был ли он добавлен автоматически или нет):

public partial class ResourceDictionaryName
{
    public ResourceDictionaryName()
    {
        InitializeComponent();
    }
}

Затем откройте файл XAML и добавьте следующий атрибут x:Class в тег ResourceDictionary:

<ResourceDictionary x:Class="MyNamespace.ResourceDictionaryName" ... />

Теперь ваш ResourceDictionary на самом деле является классом и может иметь файл с выделенным кодом.

Редактировать

В ответ на ваши изменения я бы использовал сам CheckBox и получил бы либо DataContext CheckBox, либо перебрал бы визуальное дерево, чтобы найти искомый UserControl, а затем получить его контекст данных

Простой способ:

private void CheckBox_Checked(object sender, RoutedEventArgs e)
{  
    var cbx = sender as CheckBox;
    MyViewModel viewModel = (MyViewModel)cbx.DataContext;
}

Если DataBtext CheckBox не является ViewModel, который вы ищете:

private void CheckBox_Checked(object sender, RoutedEventArgs e)
{  
    var cbx = sender as CheckBox;
    var userControl = FindAncestor<MyUserControl>(cbx);
    MyViewModel viewModel = (MyViewModel)myUserControl.DataContext;
}

public static T FindAncestor<T>(DependencyObject current)
    where T : DependencyObject
{
    current = VisualTreeHelper.GetParent(current);

    while (current != null)
    {
        if (current is T)
        {
            return (T)current;
        }
        current = VisualTreeHelper.GetParent(current);
    };
    return null;
}
...