Wednesday, February 22, 2017

XAML Designer displays property name instead of Designer Data (d:DataContext) when Binding

Leave a Comment

Context

I want my UserControl (RepositoryContainer) to be filled up with data when on XAML Designer.

I created a file named RepositoryContainerDesignData.xaml (it is in the same folder as the RepositoryContainer.xaml) and set it as d:DataContext to the UserControl.

But instead of displaying the data, XAML Designer displays the property name.

Here's a minimal example:

Design Data (RepositoryContainerDesignData.xaml)

<local:RepositoryContainer xmlns:local="clr-namespace:SystemSpecs.View.UserControls"                            Title="My Repository Title" /> 

User Control (RepositoryContainer.xaml)

<UserControl x:Class="SystemSpecs.View.UserControls.RepositoryContainer"                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"                  xmlns:local="clr-namespace:SystemSpecs.View.UserControls"                 mc:Ignorable="d"                  d:DesignHeight="100" d:DesignWidth="500"                 d:DataContext="{d:DesignData Source=RepositoryContainerDesignData.xaml}"                 DataContext="{Binding RelativeSource={RelativeSource Self}}">      <Grid>         <TextBlock Text="{Binding Path=Title}" FontSize="24" Foreground="White" HorizontalAlignment="Center" />     </Grid> </UserControl> 

Code-behind

using System.Windows.Controls;  namespace SystemSpecs.View.UserControls {     public partial class RepositoryContainer : UserControl     {         public string Title { get; set; }          public RepositoryContainer()         {             InitializeComponent();         }     } } 

Expected output:

Expected output

Output:

Output

Already tried:

Environment info:

  • Windows 10 Pro x64
  • Visual Studio Community 2015 (Version 14.9.25431.01 Update 3)
  • Microsoft .NET Framework 4.6.01586
  • More info at a Pastebin RAW to keep post clean

Am I missing something?

PS

If I create a class (e.g. public class RepositoryContainerData), create a property called Title and set an instance of this class as d:DataContext (d:DataContext="{d:DesignInstance local:RepositoryContainerData, IsDesignTimeCreatable=True}") it works as expected.

2 Answers

Answers 1

What you're trying to do works for me with possibly some minor changes. I created a new app called WpfApplication2.

RepositoryContainerDesignData.xaml contains:

<wpfApplication2:RepositoryContainer      xmlns:wpfApplication2="clr-namespace:WpfApplication2"     Title="My repository title"> </wpfApplication2:RepositoryContainer> 

The file properties are set to:

enter image description here

The control definition is

<UserControl x:Class="WpfApplication2.RepositoryContainer"              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"              d:DataContext="{d:DesignData Source=RepositoryContainerDesignData.xaml}"              mc:Ignorable="d"               d:DesignHeight="300" d:DesignWidth="300">     <Grid Background="Bisque">         <TextBlock Text="{Binding Path=Title}" FontSize="24"                     HorizontalAlignment="Center" VerticalAlignment="Center" />     </Grid> </UserControl> 

The result in the designer is

enter image description here

Not something I would usually do but I've learned something :)

Answers 2

You should use dependency properties in WPF usercontrols as they have change notification.

    public static DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(RepositoryContainer), new FrameworkPropertyMetadata(new PropertyChangedCallback(Title_Changed)));      public string Title     {         get { return (string)GetValue(TitleProperty); }         set { SetValue(TitleProperty, value); }     }       private static void Title_Changed(DependencyObject o, DependencyPropertyChangedEventArgs args)     {         RepositoryContainer thisClass = (RepositoryContainer)o;         thisClass.SetTitle();     }      private void SetTitle()     {         //Put Instance Title Property Changed code here     } 

Just replace your Title property with the code above, nothing should have to be added to make it work. SetTitle() only needs code if you need to react to the Title changed in code.

I have a c# code snippet that I created a long time ago that can make dependency properties easily, just let me know if you want it.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment