【问题标题】:WPF: Store XAML in Property and Display in ContentControlWPF:将 XAML 存储在属性中并在 ContentControl 中显示
【发布时间】:2015-03-11 12:50:18
【问题描述】:

我正在将一个 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。我想在ContentControl(或其他容器)中显示StepXaml中包含的XAML,使用类似:

在虚拟机中:

/// <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?

【问题讨论】:

    标签: c# wpf xaml contentcontrol


    【解决方案1】:

    您需要使用 XamlServices.Load() 将字符串从 XAML 反序列化为 FrameworkElement。绑定到的属性应该是 FrameworkElement 引用,而不是 string 引用。

    【讨论】:

      【解决方案2】:

      我能够通过从每个 StepXaml 中提取 CDATA 值来解决这个问题,如下所示:

          /// <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 时不需要做任何特别的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-19
        • 1970-01-01
        • 2015-02-19
        相关资源
        最近更新 更多