Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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
.net 如何基于绑定选择XAML中的画笔_.net_Wpf_Xaml_Binding_Resources - Fatal编程技术网

.net 如何基于绑定选择XAML中的画笔

.net 如何基于绑定选择XAML中的画笔,.net,wpf,xaml,binding,resources,.net,Wpf,Xaml,Binding,Resources,我在Application.xaml中定义了几百个笔刷。这些是project中多个用户控件的共享资源。他们都有带图案的钥匙:Chu YSD,Chu HJU,Chu IYO 我尝试在datatemplate中使用这些笔刷。在datatemplate中,我可以访问笔刷键的可变部分,也就是说,在datatemplate中,我可以获取YSD、HJU、IYO等字符串 如何从xaml绑定到特定的笔刷资源 目前我有这样的解决方案:在样式中,根据绑定字符串(键的可变部分),使用数据触发器将所需属性设置为指定的画

我在Application.xaml中定义了几百个笔刷。这些是project中多个用户控件的共享资源。他们都有带图案的钥匙:Chu YSD,Chu HJU,Chu IYO

我尝试在datatemplate中使用这些笔刷。在datatemplate中,我可以访问笔刷键的可变部分,也就是说,在datatemplate中,我可以获取YSD、HJU、IYO等字符串

如何从xaml绑定到特定的笔刷资源

目前我有这样的解决方案:在样式中,根据绑定字符串(键的可变部分),使用数据触发器将所需属性设置为指定的画笔。 我对这个解决方案不满意,因为Application.xaml中的笔刷列表经常会增加


我不确定是否应该使用代码隐藏,因为我想在Application.xaml中使用共享资源的内存节省优势。

这是一种看起来简单但实际上没有完美解决方案的任务(或者我没有找到)。第一种方法是使用值转换器。但它不起作用!我们需要设置资源引用,这是转换器无法正确完成的。所以,我认为正确的方法是依附行为。但您应该知道限制:只有一个属性可以应用资源。也许您可以根据自己的需求避免这种限制

附加行为允许您将具有指定名称的资源引用到指定的依赖项属性:

public static class BrushResourceKeyBehavior
{
    #region ResourceKey Property

    public static readonly DependencyProperty ResourceKeyProperty = DependencyProperty.RegisterAttached(
        "ResourceKey", typeof(object), typeof(BrushResourceKeyBehavior),
        new FrameworkPropertyMetadata(OnResourceKeyChanged));

    public static object GetResourceKey(DependencyObject dependencyObject)
    {
        return dependencyObject.GetValue(ResourceKeyProperty);
    }

    public static void SetSource(DependencyObject dependencyObject, object value)
    {
        dependencyObject.SetValue(ResourceKeyProperty, value);
    }

    #endregion

    #region TargetProperty Property

    public static readonly DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached(
        "TargetProperty", typeof(DependencyProperty), typeof(BrushResourceKeyBehavior),
        new FrameworkPropertyMetadata(OnTargetPropertyChanged));

    public static DependencyProperty GetTargetProperty(DependencyObject dependencyObject)
    {
        return (DependencyProperty)dependencyObject.GetValue(TargetPropertyProperty);
    }

    public static void SetTargetProperty(DependencyObject dependencyObject, DependencyProperty value)
    {
        dependencyObject.SetValue(TargetPropertyProperty, value);
    }

    #endregion

    private static void OnResourceKeyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var targetProperty = GetTargetProperty(dependencyObject);
        if (targetProperty != null)
        {
            if (e.NewValue == null)
            {
                dependencyObject.ClearValue(targetProperty);
            }
            else
            {
                SetResourceReference(dependencyObject, targetProperty);
            }
        }
    }

    private static void OnTargetPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var oldValue = e.OldValue as DependencyProperty;
        var newValue = e.NewValue as DependencyProperty;

        if (oldValue != null)
        {
            dependencyObject.ClearValue(oldValue);
        }

        if (newValue != null)
        {
            SetResourceReference(dependencyObject, newValue);
        }
    }

    private static void SetResourceReference(DependencyObject dependencyObject, DependencyProperty targetProperty)
    {
        var fe = dependencyObject as FrameworkElement;
        if (fe != null)
        {
            fe.SetResourceReference(targetProperty, String.Format("ch_{0}", GetResourceKey(fe)));
        }
        else
        {
            var fce = dependencyObject as FrameworkContentElement;
            if (fce != null)
            {
                fce.SetResourceReference(targetProperty, String.Format("ch_{0}", GetResourceKey(fce)));
            }
        }
    }
}
行为可以在XAML中使用,如下所示:

<ItemsControl>
    <Border local:BrushResourceKeyBehavior.Source="YSD"
            local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
            Height="20"/>
    <Border local:BrushResourceKeyBehavior.Source="HJU"
            local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
            Height="20"/>
    <Border local:BrushResourceKeyBehavior.Source="IYO"
            local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
            Height="20"/>
</ItemsControl>

上述代码相当于:

<ItemsControl>
    <Border Background="{DynamicResource ch_YSD}"
            Height="20"/>
    <Border Background="{DynamicResource ch_HJU}"
            Height="20"/>
    <Border Background="{DynamicResource ch_IYO}"
            Height="20"/>
</ItemsControl>

非常感谢这个出色的例子,你救了我的一天!:)