关于 WPF ImageBrush 的抱怨





5.00/5 (9投票s)
WPF 中的 ImageBrush
我正在使用 WPF 开发一个 3D 应用,想使用 ImageBrush
,但遇到了一些问题,所以决定将其拆分成一个小的测试应用。
我的设置如下
我只是想通过创建一个 ImageBrush
来测试它,例如改变 Button
的 Background
。所以我有以下代码
1: //THIS DOESNT WORK UNLESS I UNCOMMENT THE CODE BELOW,
2: //WHICH IS NOT EVEN RELATED
3: System.Windows.Media.ImageBrush brush =
4: new System.Windows.Media.ImageBrush();
5: BitmapImage img = new BitmapImage(
6: new Uri(@”images/image1.jpg”, UriKind.RelativeOrAbsolute));
7: brush.ImageSource = img;
8: btnImage.Background = brush;
我原本以为应该可以工作。但当我运行它时,我得到了
所以我尝试在代码中添加一张图片,现在代码变成了
1: <Window x:Class=”ImageBrush.Window1″
2: xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
3: xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
4: Title=”Window1″ Height=”300″ Width=”300″>
5: <StackPanel x:Name=”sp1″>
6: <Button x:Name=”btnImage” Margin=”10″ Height=”60″/>
7: </StackPanel>
8: </Window>
以及代码后台
1: //THIS DOESNT WORK UNLESS I UNCOMMENT THE CODE BELOW,
2: //WHICH IS NOT EVEN RELATED
3: System.Windows.Media.ImageBrush brush =
4: new System.Windows.Media.ImageBrush();
5: BitmapImage img = new BitmapImage(
6: new Uri(@”images/image1.jpg”, UriKind.RelativeOrAbsolute));
7: brush.ImageSource = img;
8: btnImage.Background = brush;
9:
10:
11: //BUT IF I UNCOMMENT THESE THE ABOVE CODE WORKS JUST FINE
12: Image img2 = new Image();
13: img2.Source = img;
14: sp1.Children.Add(img2);
这对我来说似乎有效。但我不想使用 Image
,所以这个方案不可行。我猜测这一定是 Image
可以做但 ImageBrush
不能做的一些技巧。对于 ImageBrush
,我设想我需要从程序集资源中读取。所以我搜索了一下,并在 Tamir Khason 的博客 上找到了以下代码
这允许我们做一些类似的事情
或者对于框架元素
所有这些都非常酷。但这仍然让我觉得不太对劲,所以我问我的朋友 Josh Smith 这个问题,他只是建议将图片的 **Build Action** 更改为 “Content
”。这解决了问题,壮观的结果如下所示
太棒了,不是吗。但请注意,当我们设置 **Build Action** 为 “Content
” 时,你也会失去本地化该图像的能力。(使用 Resource build action 构建的图像通过 ResourceManager
加载,这意味着它们可以用本地化卫星资源程序集中的图像替换。)
从这里开始,本博客将使用一些与 Ian Griffiths 聊天结果相关的信息。
事实上,完全有可能在 ImageBrush
中使用编译到资源中的资源,你只需要一个更具体的 URI,所以我们可以使用如下 URL
其中我们使用完全限定的 pack URI。顺便说一下,我的测试应用程序名为 ImageBrushAsResource
– 显然你需要将你的组件名称放在那里。
实际上,我们可以使用相对路径在 XAML 中为 Image
这样做
它使用 ImageSourceConverter
将该文本字符串转换为 ImageSource
,并且使用它的过程与你在代码中使用的过程略有不同。XAML 解析器会将 ImageSourceConverter
传递一个上下文对象,该对象提供一个 IUriContext
服务,让它可以发现包含 XAML 文档的基本 URI,并相对于该 URI 解析 URI。所以它对应于
这允许你使用相对 URI,如原始示例所示。它使用你的窗口的基本 URI 将其转换为完整的 URI,这将类似于 “pack://application:,,,/ImageBrush;component/window1.xaml”,因此它最终将你的相对 URI 解析为我的第一个示例使用的完全限定 URI。但这里的优势是你不需要将其硬编码到代码后台中。你只需要询问 WPF 应该使用什么基本 URI。
因此,通过在代码后台中使用这两种方法中的任何一种,你都可以避免使用 Tamir 的代码。
- 使用 Resource 的 Build Action,并使用完整的 Pack Uri
- 使用 Resource 的 Build Action,并使用
BaseUriHelper
总而言之,这是一篇相当有趣的文章,我感觉如此。