我正在尝试从我的资源字典后面的代码设置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;
}
不起作用(当然)。
我想我需要获得祖先(资源字典用户控件)的句柄,但不知道如何做到这一点 - 或者可能有另一种方式......
由于
乔
答案 0 :(得分:7)
正如@ dowhilefor的评论所说,Resource Dictionaries只是一组资源,所以不需要DataContext。但是,您可以向ResourceDictionary添加代码隐藏文件,这可能是您正在寻找的。 p>
在与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;
}