[英]WPF: Store XAML in Property and Display in ContentControl
我将XML文件反序列化为一个类,然后尝试在ContentControl中显示一些XAML(存储在该类的属性中)。
这是我的XML:
<CallSteps>
<CallStep>
<StepID>20</StepID>
<StepName>Intro</StepName>
<StepXaml>
<![CDATA[<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:uc="clr-namespace:CallTracker.Library.UserControls.BaseUserControls;assembly=CallTracker.Library">
<uc:LabelValueControl Label="TestLabel" Value="356733" />
</StackPanel>]]>
</StepXaml>
</CallStep>
<CallStep>
<StepID>30</StepID>
<StepName>Intro</StepName>
<StepXaml>
<![CDATA[<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:uc="clr-namespace:CallTracker.Library.UserControls.BaseUserControls;assembly=CallTracker.Library">
<uc:LabelValueControl Label="TestLabel2" Value="356738124315" />
</StackPanel>]]>
</StepXaml>
</CallStep>
</CallSteps>
正确反序列化为CallStep
对象的集合。 这是单个CallStep
对象的外观:
作为我的代码的一部分,我有一个CurrentCallStep
,其中包含一个CallStep
。 我想使用类似以下内容的StepXaml
在ContentControl
(或其他容器)中显示包含在StepXaml
的XAML:
在VM中:
/// <summary>
/// Current call step object
/// </summary>
public CallStep CurrentCallStep
{
get { return _CurrentCallStep; }
set
{
_CurrentCallStep = value;
NotifyPropertyChanged(m => m.CurrentCallStep);
}
}
private CallStep _CurrentCallStep;
在视图中:
<!-- CurrentCallStep contains the XAML for the current call steps to be displayed -->
<ContentControl Content="{Binding CurrentCallStep.StepXaml}"
Background="LightBlue"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
但是,这并不是将XAML转换为XAML,而只是显示如下文本:
如何在CurrentCallStep.StepXaml
获取文本以转换为XAML?
您需要使用XamlServices.Load()
将字符串从XAML反序列化为FrameworkElement
。 值得推荐的属性应该是FrameworkElement
引用,而不是string
引用。
我能够通过从每个StepXaml
提取CDATA值来解决此StepXaml
,如下所示:
/// <summary>
/// Step XAML
/// </summary>
[XmlElement("StepXaml")]
public object StepXaml
{
get { return _StepXaml; }
set
{
if (_StepXaml != value)
{
object _obj;
using (MemoryStream stream = new MemoryStream())
{
// Convert the text into a byte array so that
// it can be loaded into the memory stream.
XmlNode _node = (value as XmlNode[])[0];
if (_node is XmlCDataSection)
{
XmlCDataSection _cDataSection = _node as XmlCDataSection;
byte[] bytes = Encoding.UTF8.GetBytes(_cDataSection.Value);
// Write the XAML bytes into a memory stream.
stream.Write(bytes, 0, bytes.Length);
// Reset the stream's current position back
// to the beginning so that when it is read
// from, the read begins at the correct place.
stream.Position = 0;
// Convert the XAML into a .NET object.
_obj = XamlReader.Load(stream);
_StepXaml = _obj;
NotifyPropertyChanged(m => m.StepXaml);
}
}
}
}
}
private object _StepXaml;
ContentControl
只是简单地引用StepXaml
例如:
<!-- CallContent contains the XAML for the current call steps to be displayed -->
<ContentControl Content="{Binding CurrentCallStep.StepXaml}"
这样,在反序列化XML时,我不必做任何特别的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.