WPF:是否有资源更改触发的事件

时间:2014-04-03 15:02:38

标签: c# wpf winforms resourcedictionary

有没有办法了解特定 WPF 资源的价值变化?

我们需要在 WPF 应用程序中动态调整内容字体大小...对于 WPF 控件,我们将Control.FontSize设置为动态资源并且字体自动调整大小。不幸的是,我们还有一个嵌入式 winforms 控件,这种字体大小不能这样设置。我们的想法是订阅每个资源值更改触发的事件,并实现 winforms 控件的自定义刷新。有什么建议吗?

提前谢谢!

2 个答案:

答案 0 :(得分:7)

所以,

在考虑了所有可能的方法之后,我引入了一种新行为,该行为会在特定WPF资源的每次更改时触发事件。

可以从https://github.com/jeromerg/ResourceChangeEvent下载或克隆源代码。

public class ResourceChangeNotifierBehavior 
  : System.Windows.Interactivity.Behavior<FrameworkElement>
{
    public static readonly DependencyProperty ResourceProperty 
            = DependencyProperty.Register("Resource", 
                   typeof(object),
                   typeof(ResourceChangeNotifierBehavior),
                   new PropertyMetadata(default(object), ResourceChangedCallback));

    public event EventHandler ResourceChanged;

    public object Resource
    {
        get { return GetValue(ResourceProperty); }
        set { SetValue(ResourceProperty, value); }
    }

    private static void ResourceChangedCallback(DependencyObject dependencyObject,
                                                DependencyPropertyChangedEventArgs args)
    {
        var resourceChangeNotifier = dependencyObject as ResourceChangeNotifierBehavior;
        if (resourceChangeNotifier == null)
            return;

        resourceChangeNotifier.OnResourceChanged();
    }

    private void OnResourceChanged()
    {
        EventHandler handler = ResourceChanged;
        if (handler != null) handler(this, EventArgs.Empty);
    }
}

因此,事件处理程序OnResourceChanged可以挂钩在XAML文件中,如下所示:

<i:Interaction.Behaviors>
    <Behaviours:ResourceChangeNotifierBehavior 
                Resource="{DynamicResource MyDynamicResourceKey}"
                ResourceChanged="OnResourceChanged"/>
</i:Interaction.Behaviors>

希望,这有助于......

答案 1 :(得分:0)

我遇到了同样的问题,但如果有任何资源发生变化,我确实希望得到通知。就我而言,DynamicResource用于某些DependencyObject,而ResourceChanged不在视觉树中。因此,如果资源发生更改,则属性不会自动更新。

使用jeromerg找到的内部事件,我写了一个小扩展方法来注册public static void NotifyOnResourcesChanged(this FrameworkElement element, EventHandler onResourcesChanged) { ResourcesChangedEvent.AddMethod.Invoke(element, new object[] { onResourcesChanged }); } private static readonly EventInfo ResourcesChangedEvent = typeof(FrameworkElement).GetEvent("ResourcesChanged", BindingFlags.Instance | BindingFlags.NonPublic); 事件:

InvalidateProperty

在我的事件处理程序中,我通过Ready to be merged automatically </h4> grep -A1 "Ready to be merged automatically" 通知目标属性以强制更新。