我继承了一个WPF项目,它动态生成XAML,并将Image对象绑定到同样在代码中动态生成的位图。下面的示例代码展示了它的工作原理:
public class XamlImageStore
{
/// <summary>
/// Initializes a new <see cref="XamlImageStore"/> object.
/// </summary>
static XamlImageStore()
{
images = new Dictionary<string, BitmapSource>();
}
/// <summary>
/// Images used in XAML.
/// </summary>
private static Dictionary<string, BitmapSource> images;
internal static void AddImage(string imageID, BitmapSource image)
{
images[imageID] = image;
}
public static string GetImageId(DependencyObject obj)
{
return (string)obj.GetValue(ImageIdProperty);
}
public static void SetImageId(DependencyObject obj, string value)
{
obj.SetValue(ImageIdProperty, value);
}
public static readonly DependencyProperty ImageIdProperty =
DependencyProperty.RegisterAttached("ImageId", typeof(string), typeof(XamlImageStore), new UIPropertyMetadata("0", ImageIdChanged));
private static void ImageIdChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
Image target = obj as Image;
if (target != null)
{
string imageID = e.NewValue.ToString();
if (images.ContainsKey(imageID))
{
// Set the image source.
target.Source = images[imageID];
}
}
}
}
字符串
主应用程序窗口(应用程序命名空间和输出exe为DynamicXamlImage
):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string customImageID = "ABCD";
XamlImageStore.AddImage(customImageID, GetBitmap());
MemoryStream ms = new MemoryStream();
XmlTextWriter xamlWriter = new XmlTextWriter(ms, Encoding.UTF8);
xamlWriter.WriteStartElement("Canvas");
xamlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/xps/2005/06");
xamlWriter.WriteAttributeString("xmlns:local", "clr-namespace:DynamicXamlImage;assembly=DynamicXamlImage");
xamlWriter.WriteStartElement("Image");
xamlWriter.WriteAttributeString("local:XamlImageStore.ImageId", customImageID);
xamlWriter.WriteEndElement();
xamlWriter.WriteEndElement();
xamlWriter.Flush();
ms.Position = 0;
Canvas canvas = (Canvas)XamlReader.Load(ms);
appGrid.Children.Add(canvas);
}
private WriteableBitmap GetBitmap()
{
WriteableBitmap wb = new WriteableBitmap(20, 20, 96, 96, PixelFormats.Gray8, null);
byte[] pixels = new byte[] {
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0,
};
wb.WritePixels(new Int32Rect(0, 0, 20, 20), pixels, 20, 0);
return wb;
}
型
这是输出:
的数据
有人能解释一下这个绑定是如何工作的吗?因为我在这个方法上找不到任何东西。
我问的原因是我必须扩展XAML生成代码以支持动态生成的不透明度遮罩,并且我不知道如何使ImageBrush
以相同的方式加载遮罩。
1条答案
按热度按时间uplii1fm1#
有人能解释一下这个绑定是怎么工作的吗?
不涉及数据绑定。
XamlImageStore
由两个部分组成:BitmapSource
示例的字典ImageId
的attached property,它具有一个PropertyChanged回调,该回调将来自Dictionary的BitmapSource分配给已设置附加属性的Image元素的Source
属性。在程式码范例中,会将从
GetBitmap()
方法传回的BitmapSource加入至Dictionary,并使用索引键"ABCD"
。然后,在值为"ABCD"
的Image元素上设置attached属性,这将导致Image的Source设置为以前创建的BitmapSource。注意,
XamlImageStore
类的静态构造函数是多余的。你也可以写字符串
PropertyChangedCallback也可以写得更有效率一些:
型
还要注意,拥有这个helper类的整个想法可能是多余的。您也可以使用XAML资源,例如就像这样:
型