如何在 C# 中使用内联 XAML 轻松地在代码隐藏中创建自定义对象

How to use inline XAML in C# to easily make custom objects in code-behind

我试图用 XAML 解析器引用 LinearGradientBrush,但它无法识别对象,我得到了异常:

"Cannot create unknown type '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# 更容易,我' d 更愿意使用这种方法...

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

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

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

为了回答您的具体问题,需要在编译 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 集合之一中声明。

例如,如果您希望能够在整个程序中使用它,在许多不同的 windows 中,您可以通过将其放入 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}"/>