通过代码隐藏更改WPF矩形填充的最佳方法

时间:2012-10-23 01:52:48

标签: wpf canvas resourcedictionary

建议:代码工作正常,这个问题是关于这样做的最佳实践。

在我的项目中,矩形的填充是一个表示视频状态的画布,例如,如果用户点击播放,画布需要更改为playing,视频是结束时,画布需要更改为stopped之类的内容。我在一个资源字典中拥有代表此状态的所有画布。

我的要求是:我有一个拥有大量资源的ResourceDictionary,资源看起来像这样

<Canvas Width="48" Height="48" Clip="F1 M 0,0L 48,0L 48,48L 0,48L 0,0" x:Key="appbar_add">
    <Path Width="24" Height="24" Canvas.Left="12" Canvas.Top="12" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 22,12L 26,12L 26,22L 36,22L 36,26L 26,26L 26,36L 22,36L 22,26L 12,26L 12,22L 22,22L 22,12 Z " />
</Canvas>
<Canvas Width="48" Height="48" Clip="F1 M 0,0L 48,0L 48,48L 0,48L 0,0" x:Key="appbar_alert">
    <Path Width="22.1402" Height="20.75" Canvas.Left="12.9299" Canvas.Top="14" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 24,14C 26,14 36,33 35,34C 34,35 14,35 13,34C 12,33 22,14 24,14 Z M 24,29C 23.1716,29 22.5,29.6716 22.5,30.5C 22.5,31.3284 23.1716,32 24,32C 24.8284,32 25.5,31.3284 25.5,30.5C 25.5,29.6716 24.8284,29 24,29 Z M 22.5,20L 23,28L 25,28L 25.5,20L 22.5,20 Z " />
</Canvas>
<Canvas Width="48.0067" Height="48.0067" Clip="F1 M 0,0L 48.0067,0L 48.0067,48.0067L 0,48.0067L 0,0" x:Key="appbar_alien">
    <Path Width="22.005" Height="16.0048" Canvas.Left="12.9999" Canvas.Top="16.9998" Stretch="Fill" Fill="{DynamicResource BlackBrush}" Data="F1 M 16.9999,16.9998L 19.0002,16.9998L 19.0026,19.0027L 21.0002,18.9998L 21.0029,21.0029L 27.0038,21.0029L 26.9999,18.9998L 28.9999,18.9998L 28.9999,16.9998L 31.0002,16.9998L 31.0002,19.0001L 29.0002,19.0001L 29.0041,21.0029L 31.0043,21.0029L 31.0043,23.0032L 33.0046,23.0032L 33.0046,25.0035L 31.0043,25.0035L 31.0001,31.0001L 29.0001,31.0001L 29.0001,33.0001L 25.0035,33.0046L 25.0035,31.0043L 28.9999,30.9999L 29.004,28.0039L 19.0026,28.0039L 19.0026,31.0043L 17.0024,31.0043L 16.9999,25.0001L 15.0002,25.0001L 15.0002,29.0001L 12.9999,29.0001L 12.9999,24.9998L 14.9999,24.9998L 14.9999,22.9998L 16.9999,22.9998L 17.0024,21.0029L 19.0026,21.0029L 18.9999,19.0001L 16.9999,19.0001L 16.9999,16.9998 Z M 33.0046,25.0035L 35.0049,25.0035L 35.0049,29.0041L 33.0046,29.0041L 33.0046,25.0035 Z M 19.0026,31.0043L 23.0032,31.0043L 23.0032,33.0046L 19.0026,33.0046L 19.0026,31.0043 Z M 19.0026,23.0032L 19.0026,25.0035L 21.0029,25.0035L 21.0029,23.0032L 19.0026,23.0032 Z M 27.0038,23.0032L 27.0038,25.0035L 29.004,25.0035L 29.004,23.0032L 27.0038,23.0032 Z " />
</Canvas>
...

我想打开此资源,按名称查找一个资源,并将此资源应用于矩形的填充。其实我正在做以下事情:

 private void ChangeFill()
    {
        Collection<ResourceDictionary> appResources = Application.Current.Resources.MergedDictionaries;

        if (Application.Current.Resources.MergedDictionaries.Count > 1)
        {
            ResourceDictionary recIcones = appResources.Where(r => r.Source.OriginalString == "Resources/Icons.xaml").FirstOrDefault(); // get the properly resource dictionary

            if (recIcones != null)
            {
                Canvas x = (Canvas)recIcones["appbar_add"]; // find a espicified resource by name
                VisualBrush vBrush = new VisualBrush(x);
                rctParado.Fill = vBrush; // apply it to the rectangle
            }
        }
    }

这很好用,问题是: 这是更好的方法吗?

2 个答案:

答案 0 :(得分:2)

只需在视觉树中的某些内容上调用FindResource即可。这将自动搜索资源,根据需要递归可视树,直到找到它(包括查看应用级资源)。如果您只想搜索应用程序的资源,请使用FindResource对象上的Application方法。

对于动态分配资源,您可能可以通过数据绑定更干净,更优雅地实现相同的功能。也就是说,将Canvas'Style属性绑定到引发样式更改的任何属性,并使用转换器执行资源查找。没有你的场景的全部细节,很难更具体。

答案 1 :(得分:0)

如果填充基于状态,则建议使用转换器。

public class BrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
       return ChangeFill();
    }


}

Fill={Binding ., Converter={StaticResource BrushConverter}

您需要更改更改填充以返回画笔或更改代码:)

STE。