【问题标题】:How to use inline XAML in C# to easily make custom objects in code-behind如何在 C# 中使用内联 XAML 在代码隐藏中轻松创建自定义对象
【发布时间】:2015-03-11 23:32:12
【问题描述】:

我正在尝试使用 XAML 解析器引用 LinearGradientBrush,但它无法识别对象并且出现异常:

“无法创建未知类型'LinearGradientBrush'”

是否可以在运行时识别这种类型?

这是我正在使用的代码:

public static class CustomBrushes
{
    public static Brush LinGrad_Bevel()
    {
        
        
        StringReader sr = new StringReader(@"<LinearGradientBrush EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'>
                <GradientStop Color='#00F7F7F7' Offset='0'/>
                <GradientStop Offset='1'/>
                <GradientStop Color='Black' Offset='0.741'/>
                <GradientStop Color='Black' Offset='0.75'/>
                <GradientStop Color='White' Offset='0.25'/>
            </LinearGradientBrush>");
        XmlReader xr = XmlReader.Create(sr);


        return (Brush)XamlReader.Load(xr);
    }
}

我真的不喜欢在 XAML 中编程(尤其是因为我所做的大部分工作都是依赖于运行时程序流程的设计,但有些对象在其中制作原型比 C# 更容易,我更希望能够采用这种方法...

我读过我应该在某处包含这样的一行,但老实说我不明白为什么,如果我把它放在所有“使用”下面似乎不起作用

[assembly: XmlnsDefinition("http://schemas.microsoft.com/netfx/2007/xaml/presentation" , "System.Windows.Media")]

无论如何,如果对 C# 代码文件中 XAML 的运行时解析提供任何帮助,我们将不胜感激。

【问题讨论】:

  • SOC(关注点分离)有待完成!如果您确实需要这样做,请使用 WPF API 中的对象。
  • 这个特定 UserControl 的整个代码都是在代码隐藏中完成的。我对 XAML 不太熟悉如何在运行时对 GUI 进行大量更改而不使用 C#,这正是 UserControl 所做的(大量添加和减去网格对象以及调整它们的大小等) - 但我可以在 C# 中完成。我只是认为设计一个我喜欢的画笔并解析它会更容易,而不是用 C# 手动写出来......

标签: c# wpf xaml xamlparseexception xamlreader


【解决方案1】:

要回答您的具体问题,需要在编译 XAML 时提供命名空间声明。最简单的方法是将它们插入到您的字符串中。例如:

StringReader sr = new StringReader(@"
    <LinearGradientBrush
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
        xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
        EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'>
    <GradientStop Color='#00F7F7F7' Offset='0'/>
    <GradientStop Offset='1'/>
    <GradientStop Color='Black' Offset='0.741'/>
    <GradientStop Color='Black' Offset='0.75'/>
    <GradientStop Color='White' Offset='0.25'/>
</LinearGradientBrush>");
XmlReader xr = XmlReader.Create(sr);

return (Brush)XamlReader.Load(xr);

现在,话虽如此,我会说上面的方法在我看来是最不理想的方法。如果您想要一个可重用的 Brush 对象并且您想使用 XAML 来声明它而不是通过实际的 WPF 编程 API,我认为更好的方法是将声明放在相关的 Resources 集合之一中在你的程序中。

例如,如果您希望能够在整个程序中,在多个不同的窗口中使用它,您可以通过将其放入您的 App.xaml 文件中来使其成为全局资源:

<Application x:Class="TestSO28999367XamlReader.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <LinearGradientBrush x:Key="beveledLinearGradientBrush"
                    EndPoint='0.5,1' MappingMode='RelativeToBoundingBox' StartPoint='0.5,0'>
      <GradientStop Color='#00F7F7F7' Offset='0'/>
      <GradientStop Offset='1'/>
      <GradientStop Color='Black' Offset='0.741'/>
      <GradientStop Color='Black' Offset='0.75'/>
      <GradientStop Color='White' Offset='0.25'/>
    </LinearGradientBrush>
  </Application.Resources>
</Application>

如果您的使用仅限于一个 Window 对象或什至其中的某个子元素,您可以在该对象的 Resources 集合中添加声明,而不是将其放入 App.xaml 中。

不管怎样,你可以用这个表达式来访问它:

(Brush)FindResource("beveledLinearGradientBrush")

当然,您可以为资源创建任何您想要的密钥……它不必是beveledLinearGradientBrush

您仍然可以使用它来初始化一些代码隐藏资源,方法是使用上面的 C# 表达式来检索对象。但是,请注意,当您按照上述方式进行操作时,画笔也可以通过表达式"{StaticResource beveledLinearGradientBrush}" 在任何 XAML 中直接使用。

例如:

<Border Background="{StaticResource beveledLinearGradientBrush}"/>

【讨论】:

  • 太好了,我承认我有种想法,也许我可以在资源字典中声明对象,然后在我发表这篇文章后仍然可以在 C# 中访问它们 - 但我并没有真正考虑过像以前那样。问题是我的用户控件对象将位于 DLL 中,因此我不想对应用程序进行任何调整以使用用户控件,我仍在努力弄清楚 XAML 究竟是如何实现的包含在 DLL 中
  • 我是 WPF 的新手 - 抱歉,我对此感到迷茫 - 这超出了我关于编写 C# 的正常思维方式
  • @ThisHandleNotInUse:XAML 资源在 DLL 中工作正常。您在那里使用它们时遇到过什么特殊困难吗?
  • 我一周前开始使用 WPF - 我还没有专门研究如何精确地做到这一点。如果我的用户控件完全用 C# 编写(我正在处理的是 - 不是一盎司 XAML),是否有办法向其中添加资源库,只有在创建控件时才会加载?
  • 我认为我无法弄清楚如何从应用程序中获取正确引用 DLL 中 XAML 文件的路径。我只是不明白 DLL 中资源路径的性质
猜你喜欢
  • 2012-07-13
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多