从后面的代码设置ResourceDictionary DataContext

时间:2011-09-28 16:57:04

标签: wpf xaml resourcedictionary

我正在尝试从我的资源字典后面的代码设置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;
    }

不起作用(当然)。

我想我需要获得祖先(资源字典用户控件)的句柄,但不知道如何做到这一点 - 或者可能有另一种方式......

由于

1 个答案:

答案 0 :(得分:7)

正如@ dowhilefor的评论所说,Resource Dictionaries只是一组资源,所以不需要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本身并获取CheckBox的DataContext,或者遍历Visual Tree以查找我正在寻找的UserControl,然后获取它的数据上下文

简单方法:

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

如果CheckBox的DataContext不是您正在寻找的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;
}