Set a ResourceDictionary DataContext from code behind

笑着哭i 提交于 2019-12-19 10:14:24

问题


I'm trying to set a ResourceDictionary DataContext, from the code behind of my Resource Dictionary.

I have a Data Template that uses its own style (the Resource Dictionary), the style contains a checkbox with its own style :

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

In the CheckBox_Checked event, I want to reference the dictionary's parent (a User Control) View Model, to execute a function, but because Resource Dictionaries do not have a DataContext property setting the DataContext from inside a control event, like this :

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

doesn't work (of course).

I think I need to get a handle to the Ancestor (the Resource Dictionary User Control), but don't know how to do this - or there may be another way..

Thanks

Joe


回答1:


As @dowhilefor's comment says, Resource Dictionaries are simply a collection of resources, so do not need a DataContext. You can, however, add a code-behind file to the ResourceDictionary, which may be what you're looking for.

Create a new class in the same directory as your ResourceDictionary and name it ResourceDictionaryName.xaml.cs. It will become the code-behind file for your ResourceDictionary.

Open the new .cs file, and make sure the following is there (Can't remember if it's added automatically or not):

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

Next, open your XAML file and add the following x:Class attribute to the ResourceDictionary Tag:

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

Now your ResourceDictionary is actually a class, and can have a code-behind file.

Edit

In response to your edits, I would use the CheckBox itself and get either the CheckBox's DataContext, or traverse up the Visual Tree to find the UserControl I'm looking for and then get it's Data Context

Easy way:

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

If CheckBox's DataContext is not the ViewModel you're looking for:

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;
}


来源:https://stackoverflow.com/questions/7586810/set-a-resourcedictionary-datacontext-from-code-behind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!