Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何向UserControl添加更多资源_Wpf_Xaml_Wpf Controls_Resourcedictionary - Fatal编程技术网

Wpf 如何向UserControl添加更多资源

Wpf 如何向UserControl添加更多资源,wpf,xaml,wpf-controls,resourcedictionary,Wpf,Xaml,Wpf Controls,Resourcedictionary,我们是否可以在使用点向UserControl添加新资源,而不清除UserControl定义的资源 对于exmaple,这里有一个UserControl: <UserControl x:Class="MyControl"> <UserControl.Resources> <!--Resource1--> <!--Resource2--> </UserControl.Resources> </UserContr

我们是否可以在使用点向
UserControl
添加新资源,而不清除
UserControl
定义的资源

对于exmaple,这里有一个
UserControl

<UserControl x:Class="MyControl">
  <UserControl.Resources>
    <!--Resource1-->
    <!--Resource2-->
  </UserControl.Resources>
</UserControl>

这样做会清除Resource1和Resource2,剩下的只有Resource3。我也试过
,也有同样的效果。我正在寻找Resource3添加到现有资源列表中的方法。

据我所知,这是不可能的。但您可以通过代码或附加属性来实现这一点。例如,让我们定义这样的属性:

public static class ResourceExtensions {
    public static readonly DependencyProperty AdditionalResourcesProperty = DependencyProperty.RegisterAttached(
        "AdditionalResources", typeof(ResourceDictionary), typeof(ResourceExtensions), new PropertyMetadata(null, OnAdditionalResourcesChanged));

    private static void OnAdditionalResourcesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var fe = d as FrameworkElement;
        if (fe == null)
            throw new Exception("Cannot add resources to type " + d.GetType());
        if (fe.Resources == null)
            fe.Resources = new ResourceDictionary();
        var dict = e.NewValue as ResourceDictionary;
        if (dict != null) {                                
            foreach (DictionaryEntry resource in dict) {
                fe.Resources[resource.Key] = resource.Value;
            }
        }
    }

    public static void SetAdditionalResources(DependencyObject element, ResourceDictionary value) {
        element.SetValue(AdditionalResourcesProperty, value);
    }

    public static ResourceDictionary GetAdditionalResources(DependencyObject element) {
        return (ResourceDictionary) element.GetValue(AdditionalResourcesProperty);
    }
}
它将做的是获取资源字典并将所有值从它复制到目标控件的资源字典(覆盖现有资源的值)。用途是:

<Window.Resources>
    <ResourceDictionary>
        <!-- This is resource dictionary to merge with target -->
        <ResourceDictionary x:Key="overrideResources">
            <Brush x:Key="foreground">Yellow</Brush>
        </ResourceDictionary>
    </ResourceDictionary>
</Window.Resources>
<wpfApplication1:UserControl1 wpfApplication1:ResourceExtensions.AdditionalResources="{StaticResource overrideResources}"/>

如果我将带有附加属性的上述方法应用于此
UserControl
,则其中的文本将变为黄色(为红色),因为带键的
画笔
前台被覆盖,但带键的
样式
测试保持不变,并且我使用了
动态资源
。如果我改用了
StaticResource
,则资源字典中的资源仍将更改,但控件不会反映该更改,因为使用
StaticResource
它不会监视资源中的更改。

Resource3可能应该在窗口中。资源。@Clemens:我也试过了。问题是我需要覆盖(可以说)在
UserControl
中定义的特定资源的定义。这仅在我将新资源放在
MyControl.Resources
部分时有效。把它放在其他地方似乎没有效果。@Clemens:显示了我试图解决的问题。谢谢。这似乎是目前唯一的出路。我接受你的回答。如果有更好的地方,我们将进行回顾。请注意,从代码中比从xaml中更容易。从代码中,您只需执行“yourControl.Resources[“Color1”]=Color.White”并完成。但是使用DynamicResource而不是StaticResource即使在那时也是相关的。
<Window.Resources>
    <ResourceDictionary>
        <!-- This is resource dictionary to merge with target -->
        <ResourceDictionary x:Key="overrideResources">
            <Brush x:Key="foreground">Yellow</Brush>
        </ResourceDictionary>
    </ResourceDictionary>
</Window.Resources>
<wpfApplication1:UserControl1 wpfApplication1:ResourceExtensions.AdditionalResources="{StaticResource overrideResources}"/>
<UserControl.Resources>
    <Brush x:Key="foreground">Red</Brush>
    <Style x:Key="test" TargetType="TextBlock">
        <!-- Note DynamicResource here -->
        <Setter Property="Foreground" Value="{DynamicResource foreground}" />
    </Style>
</UserControl.Resources>
<StackPanel>
    <TextBlock Text="test" FontSize="12" Style="{StaticResource test}" />
</StackPanel>