如何在 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}"/>
我试图用 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}"
.
例如:
<Border Background="{StaticResource beveledLinearGradientBrush}"/>