Trying to use a UserControl in a DataTemplate

Karl Ronsaria 25 Reputation points
2023-04-13T04:49:39.4+00:00

I'm new to WinUI 3, and I'm trying to make a UserControl and use it inside a DataTemplate. The UserControl composes a circle (Ellipse) and has a DependencyProperty for the circle's fill color. Whenever I use the UserControl normally, by giving it a hard-coded random color, it works. And whenever I use any other control in the DataTemplate with a binding, it works. But when I try to use the UserControl in the DataTemplate, the resulting circle is blank.

I've looked this problem up several times, and none of the solutions I've found worked. Would someone be willing to look at my code and see if I'm missing something?

Here are some snippets from my code:

Definition


CircleFrame.xaml

<UserControl
    x:Class="DragAndDrop.CircleFrame"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DragAndDrop"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Ellipse
        Height="50"
        Width="50"
        Margin="5"
        >
        <Ellipse.Fill>
            <SolidColorBrush
                x:Name="colorBrush"
                Color="{Binding Path=FillColor, ElementName=CircleFrame, Mode=TwoWay}"
                />
        </Ellipse.Fill>
    </Ellipse>
</UserControl>

CircleFrame.xaml.cs

public sealed partial class CircleFrame : UserControl
{
    public static readonly DependencyProperty FillColorProperty = DependencyProperty.Register(
        nameof(FillColor),
        typeof(string),
        typeof(CircleFrame),
        new PropertyMetadata(default(string))
    );

    public CircleFrame()
    {
        this.InitializeComponent();
    }

    public string FillColor
    {
        get => (string)GetValue(FillColorProperty);
        set => SetValue(FillColorProperty, value);
    }
}

Use


MainWindow.xaml

<GridView
    x:Name="gridView"
    Grid.Row="0"
    Grid.Column="1"
    Grid.ColumnSpan="1"
    Margin="5"
    >
    <GridView.ItemTemplate>
        <DataTemplate>
            <StackPanel
                Orientation="Horizontal"
                Background="#1e1e1e"
                >
                <local:CircleFrame
                    FillColor="{Binding Color}"
                    />
                <StackPanel
                    MinWidth="150"
                    Margin="5"
                    >
                    <TextBlock
                        Text="{Binding Name}"
                        FontWeight="Bold"
                        />
                    <TextBlock
                        Text="{Binding Description}"
                        />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
</GridView>

MainWindow.xaml.cs

public sealed partial class MainWindow : Window
{
    public List<Item> Items = new();

    public MainWindow()
    {
        this.InitializeComponent();
        Items.Add(new Item() { Name = "What", Description = "What the..." });
        gridView.ItemsSource = Items;
    }
}

public class Item
{
    public int Id { get; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Color { get; set; }

    private static int _numberItems = 0;
    public static readonly List<Item> All = new();

    public Item()
    {
        Id = Item._numberItems;
        Item.All.Add(this);
        Item._numberItems++;
        Color = $"#{new Random().Next(0, 0xFFFFFF):X6}";
    }
}
Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
731 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,385 questions
0 comments No comments
{count} votes

Accepted answer
  1. Junjie Zhu - MSFT 15,831 Reputation points Microsoft Vendor
    2023-04-13T10:10:17.68+00:00

    Hello @Karl Ronsaria ,

    Welcome to Microsoft Q&A!

    In the case of multiple nested binds, it is recommended to use x:bind, which is more reliable. You need to modify the program in two places:

    CircleFrame.xaml

    <Ellipse
            Height="50"
            Width="50"
            Margin="5"
            Stroke="Black"
            >
            <Ellipse.Fill>
                <SolidColorBrush
                    x:Name="colorBrush"
            Color="{x:Bind FillColor, Mode=TwoWay}"
            />
    </Ellipse.Fill>
    
    </Ellipse>   
    

    CircleFrame.xaml.cs If you use x:bind, you need to give DependencyProperty an initial value.

    public static readonly DependencyProperty FillColorProperty = DependencyProperty.Register(
            nameof(FillColor),
            typeof(string),
            typeof(CircleFrame),
            new PropertyMetadata($"#ffffff")
            );
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful