[英]Why is find anchestor binding to attached property not working via value converter?
我有一本資源字典,其中包含作為矢量圖形的圖標。 一個附加的屬性允許我定義圖標的顏色。 當我使用圖標作為靜態資源時,從資源字典到附加到圖像的顏色的綁定正在起作用。 但是,當我將綁定與值轉換器一起使用時,顏色綁定不起作用。
有人知道為什么嗎?
這里的用法示例:
<!-- OK, smile is green -->
<Image Source="{StaticResource MaterialMood}" svg:Image.Brush="Green" />
<!-- Not OK, simle is black -->
<Image Source="{Binding Image,Converter={StaticResource GoogleMaterialSource}}" svg:Image.Brush="Green" />
ResourceDictionary.xaml:
<DrawingImage x:Key="MaterialMood" x:Shared="False">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup>
<DrawingGroup.ClipGeometry>
<RectangleGeometry Rect="0,0,24,24" />
</DrawingGroup.ClipGeometry>
<GeometryDrawing Brush="{Binding Path=(svg:Image.Brush),RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Image}},FallbackValue=Black}">
<GeometryDrawing.Geometry>
<PathGeometry FillRule="Nonzero" Figures="M11.99,2C6.47,2 2,6.48 2,12 2,17.52 6.47,22 11.99,22 17.52,22 22,17.52 22,12 22,6.48 17.52,2 11.99,2z M12,20C7.58,20 4,16.42 4,12 4,7.58 7.58,4 12,4 16.42,4 20,7.58 20,12 20,16.42 16.42,20 12,20z M15.5,11C16.33,11 17,10.33 17,9.5 17,8.67 16.33,8 15.5,8 14.67,8 14,8.67 14,9.5 14,10.33 14.67,11 15.5,11z M8.5,11C9.33,11 10,10.33 10,9.5 10,8.67 9.33,8 8.5,8 7.67,8 7,8.67 7,9.5 7,10.33 7.67,11 8.5,11z M12,17.5C14.33,17.5,16.31,16.04,17.11,14L6.89,14C7.69,16.04,9.67,17.5,12,17.5z" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
C#:
public enum MaterialImage
{
Mood
}
public class GoogleMaterialSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return null;
var imageName = string.Format("Material{0}", value);
if (!Application.Current.Resources.Contains(imageName)) return null;
var image = Application.Current.Resources[imageName] as DrawingImage;
return image == null ? null : image.Clone(); // `x:Shared = false;` ???
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public static class Image
{
public static readonly DependencyProperty BrushProperty = DependencyProperty.RegisterAttached(
"Brush",
typeof(Brush),
typeof(Image),
new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.Inherits));
[TypeConverter(typeof(BrushConverter))]
public static Brush GetBrush(DependencyObject element)
{
return (Brush)element.GetValue(Image.BrushProperty);
}
[TypeConverter(typeof(BrushConverter))]
public static void SetBrush(DependencyObject element, Brush value)
{
element.SetValue(Image.BrushProperty, value);
}
}
public partial class MainWindow : Window
{
public static readonly DependencyProperty ImageProperty = DependencyProperty.Register("Image",
typeof (MaterialImage), typeof (MainWindow), new PropertyMetadata(MaterialImage.Mood));
public MaterialImage Image
{
get { return (MaterialImage)this.GetValue(MainWindow.ImageProperty); }
set { this.SetValue(MainWindow.ImageProperty, value); }
}
public MainWindow()
{
this.DataContext = this;
this.InitializeComponent();
}
}
感謝King King的評論,我能夠更改代碼,因此現在可以使用了。 現在不再使用IValueConverter綁定到枚舉值,而是使用另一個附加屬性來設置圖像源:
XAML:
<Image svg:Image.Brush="Green" svg:Image.Source="{Binding Image}" />
CS:
public static class Image
{
// color stuff goes here
...
public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached("Source", typeof(MaterialImage), typeof(Image), new FrameworkPropertyMetadata(MaterialImage.Mood, OnSourceChangedCallback));
public static MaterialImage GetSource(DependencyObject element) { return (MaterialImage)element.GetValue(Image.SourceProperty); }
public static void SetSource(DependencyObject element, MaterialImage value) { element.SetValue(Image.SourceProperty, value); }
private static void OnSourceChangedCallback(DependencyObject source, DependencyPropertyChangedEventArgs args)
{
var image = (System.Windows.Controls.Image)source;
if (args.NewValue == null)
{
image.Source = null;
return;
}
var resourceName = string.Format("Material{0}", args.NewValue);
if (!Application.Current.Resources.Contains(resourceName))
{
image.Source = null;
return;
}
image.Source = Application.Current.Resources[resourceName] as DrawingImage;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.