0

I'm trying to get design data to show up in my designer preview. The UserControl works fine when I run the program; however I can't get the designer to populate with values.

First off, my UserControl named SignalStrengthControl

<UserControl x:Class="Connection.SignalStrengthControl"
             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:Connection"
             mc:Ignorable="d" 
             d:DesignHeight="53.833" d:DesignWidth="100.917"
             d:DataContext="{d:DesignData Source=DesignData/SignalStrengthControlDesignData.xaml}">
    <Grid Background="Transparent">
        <Grid.Resources>
            <SolidColorBrush x:Key="OnColor" Color="#FF4a6bc8"></SolidColorBrush>
            <SolidColorBrush x:Key="OffColor" Color="#50FFFFFF"></SolidColorBrush>
            <local:RatingConverter x:Key="RatingConverter" OnBrush="{StaticResource OnColor}" OffBrush="{StaticResource OffColor}" />

            <Style TargetType="Rectangle">
                <Setter Property="VerticalAlignment" Value="Bottom" />
            </Style>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width=".4*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width=".4*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width=".4*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width=".4*"></ColumnDefinition>
            <ColumnDefinition Width="1*"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Grid Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="4*"></RowDefinition>
                <RowDefinition Height="1*"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="1"
                       Fill="{Binding Path=RatingValue, ConverterParameter=1, Converter={StaticResource RatingConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:SignalStrengthControl}}}"
                       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                       Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
        </Grid>

        <Grid Grid.Column="2">
            <Grid.RowDefinitions>
                <RowDefinition Height="3*"></RowDefinition>
                <RowDefinition Height="2*"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="1"
                       Fill="{Binding Path=RatingValue, ConverterParameter=2, Converter={StaticResource RatingConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:SignalStrengthControl}}}"
                       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                       Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
        </Grid>

        <Grid Grid.Column="4">
            <Grid.RowDefinitions>
                <RowDefinition Height="2*"></RowDefinition>
                <RowDefinition Height="3*"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="1"
                       Fill="{Binding Path=RatingValue, ConverterParameter=3, Converter={StaticResource RatingConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:SignalStrengthControl}}}"
                       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                       Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
        </Grid>

        <Grid Grid.Column="6">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"></RowDefinition>
                <RowDefinition Height="4*"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="1"
                       Fill="{Binding Path=RatingValue, ConverterParameter=4, Converter={StaticResource RatingConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:SignalStrengthControl}}}"
                       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                       Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
        </Grid>

        <Grid Grid.Column="8">
            <Grid.RowDefinitions>
                <RowDefinition Height="0*"></RowDefinition>
                <RowDefinition Height="5*"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle Grid.Row="1"
                       Fill="{Binding Path=RatingValue, ConverterParameter=5, Converter={StaticResource RatingConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:SignalStrengthControl}}}"
                       Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
                       Height="{Binding ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"/>
        </Grid>
    </Grid>
</UserControl>

You can see that I have an ignorable DataContext which points to some design data (no issues finding the file). The idea behind this UserControl is that it contains an enum dependency property and it has an enum converter which controls the fill of bars which creates something like a wifi signal strength indicator.

<local:SignalStrengthControlDesignData
    xmlns:local="clr-namespace:Connection.DesignData"
    xmlns:connection="clr-namespace:Connection"
    xmlns:markup="http://schemas.microsoft.com/winfx/2006/xaml"
    RatingValue="FourBars"
/>
<!--RatingValue="{markup:Static connection:SignalStrength.FourBars}"-->

Here is my SignalStrengthControlDesignData.xaml. I tried the commented out code and it doesn't work either. I believe "FourBars" is being interpreted as an enum because autocomplete says it's an enum member. Below is the design data code behind.

internal sealed class SignalStrengthControlDesignData
{
    public SignalStrength RatingValue { get; set; }
}

Here's the code behind for the SignalStrengthControl, has the dependency property, enum and converter.

public partial class SignalStrengthControl 
{
    public SignalStrengthControl()
    {
        InitializeComponent();
    }

    public SignalStrength RatingValue
    {
        get { return (SignalStrength)GetValue(RatingValueProperty); }
        set { SetValue(RatingValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for RatingValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty RatingValueProperty =
        DependencyProperty.Register("RatingValue", typeof(SignalStrength), typeof(SignalStrengthControl), new UIPropertyMetadata(SignalStrength.ZeroBars));
}

public enum SignalStrength
{
    ZeroBars,
    OneBar,
    TwoBars,
    ThreeBars,
    FourBars,
    FiveBars
}

public class RatingConverter : IValueConverter
{
    public Brush OnBrush { get; set; }
    public Brush OffBrush { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || parameter == null)
        {
            return Brushes.Transparent;
        }

        // There are five bars in the xaml with each having a barNumber associated with it. The smallest bar
        // on the left has a barNumber value of 1, the largest has 5.
        int barNumber;
        if (int.TryParse(parameter.ToString(), out barNumber))
        {
            var signalStrengthRating = (int)value; 
            if (barNumber <= signalStrengthRating)
            {
                return this.OnBrush;
            }
            return this.OffBrush;
        }
        return Brushes.Transparent;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

I've also replaced this.OnBrush with Brushes.WhateverColor and it still does not appear in the designer.

I know that one way to get something showing is to have a FallBackValue but in the future I may need something more complex than this showing up.

Open to all suggestions.

user2619824
  • 478
  • 1
  • 5
  • 20

1 Answers1

0

I changed the implementation to use a custom control that overrides the ProgressBar WPF control. Then the design data showed up as expected.

user2619824
  • 478
  • 1
  • 5
  • 20