0
votes

If anyone knows the solution to create dynamic xaml using data related (DataContext="{Binding User}") or static data (DataContext="{Binding User, Source={StaticResource Locator}}")?

Such a solution could be saved on the controls hidden and additional fields (Visibility="{Binding IsAnonim, Converter={StaticResource VisibilityConverter}}"). And XAML had to only what is needed in this case and was not saturated with unnecessary controls.

Code ("if (IsUser) { }") that could be exercised at moment of rendering.

Example below:

    <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        d:DesignHeight="300" d:DesignWidth="400">
        <Grid x:Name="LayoutRoot" DataContext="{Binding User}">
            <StackPanel>
<? if (IsUser) { ?>
   <TextBox Text="{Binding UserName, Mode=TwoWay}" />
   <PasswordBox Text="{Binding UserPass, Mode=TwoWay}" />
<? } else if (IsAnonim) { ?>
   <TextBox Text="{Binding AnonimName, Mode=TwoWay}" />
<? } ?>
                <TextBox Text="{Binding MsgText, Mode=TwoWay}" />
                <Button Content="Button" Command="{Binding PostCommand}" />        
            </StackPanel>
        </Grid> </UserControl>

P.S. Other solutions are possible. Thank you.

1
If there are objects of different types in your User property, you may use different DataTemplates and set their DataType appropriately. Otherwise use a ContentControl with an appropriate DataTemplateSelector in its ContentTemplateSelector property. You may take a look at the Data Templating Overview article on MSDN. - Clemens
I'll have to write two templates. I'm doing it this way and it is time consuming. - ADM-IT

1 Answers

0
votes

Its simple with binding and visibilty

<UserControl
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   d:DesignHeight="300" d:DesignWidth="400">
   <UserControl.Resources>
     <Convertors:BooleanToInvisibiltyConverterx:Key="booleanToInvisibiltyConverter"/>
     <BooleanToVisibiltyConverterx:Key="booleanToVisibiltyConverter"/>
   </UserControl.Resources>

   <Grid x:Name="LayoutRoot" DataContext="{Binding User}">
     <StackPanel>
       <StackPanel Visibility="{Binding IsUser, Converter={StaticResource booleanToVisibiltyConverter}}">
         <TextBox Text="{Binding UserName, Mode=TwoWay}" />
         <PasswordBox Text="{Binding UserPass, Mode=TwoWay}" />
      </StackPanel>
      <StackPanel Visibility="{Binding IsUser, Converter={StaticResource booleanToInvisibiltyConverter}}">
        <TextBox Text="{Binding AnonimName, Mode=TwoWay}" />
      </StackPanel
      <TextBox Text="{Binding MsgText, Mode=TwoWay}" />
      <Button Content="Button" Command="{Binding PostCommand}" />        
    </StackPanel>
  </Grid>
</UserControl>

You just need to define the resources and create an InvisibiltyConverter

/// <summary>The boolean to invisibility converter.</summary>
public class BooleanToInvisibilityConverter : IValueConverter
{
    /// <summary>The convert.</summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target type.</param>
    /// <param name="parameter">The parameter.</param>
    /// <param name="culture">The culture.</param>
    /// <returns>The <see cref="object"/>.</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null 
            && (bool)value == true)
        {
            return Visibility.Collapsed;
        }

        return Visibility.Visible;
    }

    /// <summary>The convert back.</summary>
    /// <param name="value">The value.</param>
    /// <param name="targetType">The target type.</param>
    /// <param name="parameter">The parameter.</param>
    /// <param name="culture">The culture.</param>
    /// <returns>The <see cref="object"/>.</returns>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

However as the complexity increases you will find that keeping all of your UI in a single xaml file becomes an impossibilty. At that point you need to learn about Data Templating as @Clemens suggested in the comments. See Data templating overview