37585

WPF: Store XAML in Property and Display in ContentControl

Question:

I am deserializing a XML file into a class and then trying to display some XAML (stored in a property in the class) in a ContentControl.

Here is my 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>

This correctly deserializes to a collection of CallStep objects. Here is what a single CallStep object looks like:

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/6Q79d.png" data-original="https://i.stack.imgur.com/6Q79d.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

As part of my code I have a CurrentCallStep which contains a single CallStep. I would like to display the XAML contained in StepXaml within a ContentControl (or some other container) using something like:

in VM:

/// <summary> /// Current call step object /// </summary> public CallStep CurrentCallStep { get { return _CurrentCallStep; } set { _CurrentCallStep = value; NotifyPropertyChanged(m => m.CurrentCallStep); } } private CallStep _CurrentCallStep;

in View:

<!-- CurrentCallStep contains the XAML for the current call steps to be displayed --> <ContentControl Content="{Binding CurrentCallStep.StepXaml}" Background="LightBlue" HorizontalAlignment="Center" VerticalAlignment="Center" />

This however is not converting the XAML to XAML but rather just showing the text like:

<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/s9BFV.png" data-original="https://i.stack.imgur.com/s9BFV.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

How can I get the text in CurrentCallStep.StepXaml to convert to XAML?

Answer1:

You need to use XamlServices.Load() to deserialize the string from XAML to a FrameworkElement. The property that is bounnd to should be a FrameworkElement reference, not a string reference.

Answer2:

I was able to solve this by extracting the CDATA value from each StepXaml as follows:

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

The ContentControl simply refers to the StepXaml like:

<!-- CallContent contains the XAML for the current call steps to be displayed --> <ContentControl Content="{Binding CurrentCallStep.StepXaml}"

Doing it this way I didn't have to do anything special while deserializing the XML.

Recommend

  • What is the point of key-value coding?
  • Apache Flink read Avro byte[] from Kafka
  • Deserialize JSON when type can be different
  • Validate textbox to accept only valid datetime value using DataAnnotations in mvc3
  • How to store WindowsIdentity for use at a later, indeterminate time
  • Git cleanup/garbage collection on remote VSO git repository
  • I don't get what's the difference between format() and … (python)
  • How can I emulate a recursive type definition in C++?
  • Java Garbage collection, setting reference to null
  • How to retrieve multiple columns from non-entity type sql query?
  • Organizing large javascript files [closed]
  • Refactoring advice: maps to POJOs
  • JavaScriptCore External Arrays
  • Single django queryset to get n adjacent items
  • Double dispatch in Java example
  • conditions for accessors in Coldfusion ORM
  • Django return user model id with L
  • Where these are stored?
  • In Java, how can I construct a File from a resource?
  • abstracting over a collection
  • How can I tell a form not to dispose a particular control when it closes?
  • Do query loads all the data in memory
  • Find group of records that match multiple values
  • ASP.NET MVC Application won't update some controllers
  • Multicolored edittext hint
  • Redux Form - Not able to type anything in input
  • Date Conversion from yyyy-mm-dd to dd-mm-yyyy
  • Debug.DrawLine not showing in the GameView
  • How can I sort a a table with VBA with given text condition?
  • All Classes Conforming to Protocol Inherit Default Implementation
  • CSS Linear-gradient formatting issue accross different browsers
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Redux, normalised entities and lodash merge
  • Do create extension work in single-user mode in postgres?
  • AT Commands to Send SMS not working in Windows 8.1
  • retrieve vertices with no linked edge in arangodb
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • How do I configure my settings file to work with unit tests?
  • Is it possible to post an object from jquery to bottle.py?
  • Python/Django TangoWithDjango Models and Databases