Home > database >  Using UserControl with custom properties in ItemsControl
Using UserControl with custom properties in ItemsControl

Time:11-05

I want to use a custom UserControl in an ItemsControl but it is not working.

A minimalistic example:

Project.Controls.UserControl1.xaml

<UserControl x:Class="Project.Controls.UserControl1"
         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:Project.Controls"
         mc:Ignorable="d" 
         Height="50" Width="100">
    <Grid Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0" Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:UserControl1}}, Path=Text1}"/>
        <Label Grid.Column="1" Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:UserControl1}}, Path=Text2}"/>
    </Grid>


</UserControl>

Project.Controls.UserControl1.xaml.cs

using System.Windows;
using System.Windows.Controls;


namespace Project.Controls
{
    /// <summary>
    /// Interaktionslogik für UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        public string Text1
        {
            get { return (string)GetValue(Text1Property); }
            set { SetValue(Text1Property, value); }
        }

        public readonly DependencyProperty Text1Property =
            DependencyProperty.Register("Text1", typeof(string), typeof(UserControl1));

        public string Text2
        {
            get { return (string)GetValue(Text2Property); }
            set { SetValue(Text2Property, value); }
        }
        public readonly DependencyProperty Text2Property =
            DependencyProperty.Register("Text2", typeof(string), typeof(UserControl1));
    }
}

Project.Controls.UserControl2.xaml

<UserControl x:Class="Project.Controls.UserControl2"
             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:Project.Controls.Elements"
             mc:Ignorable="d" 
             Height="450" Width="800">
    <Grid Background="Gray">

        <ItemsControl x:Name="MyItemControl">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:UserControl1 Text1="{Binding Text1}" Text2="{Binding Text2}" Margin="10"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </Grid>
</UserControl>

Project.Controls.UserControl2.xaml.cs

public partial class UserControl2 : UserControl
    {
        public UserControl2()
        {
            InitializeComponent();
            MyItemControl.ItemsSource = new List<MyListItem>()
            {
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
                new MyListItem("a", "b"),
            };
        }
    }

here i have used the class MyListItem:

public class MyListItem
    {
        public string Text1 { get; set; }
        public string Text2 { get; set; }

        public MyListItem(string text1, string text2)
        {
            Text1 = text1;
            Text2 = text2;
        }
    }

In the mainWindow I use UserControl2 like this:

<Window x:Class="Project.MainWindow"
        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"
        xmlns:local="clr-namespace:Project"
        xmlns:controls="clr-namespace:Project.Controls"
        mc:Ignorable="d"
        Title="Test" Height="800" Width="1280" >
    <Grid>

        <controls:UserControl2/>


    </Grid>
</Window>

Now my problem: I either get the error

System.Windows.Markup.XamlParseException: ""Binding" cannot be set for the "Text1" property of type "UserControl1". "Binding" can be set only for a DependencyProperty of a DependencyObject."

CodePudding user response:

The identifier field of a dependency property must be declared as a static field:

public static readonly DependencyProperty Text1Property =
    DependencyProperty.Register(
        nameof(Text1),
        typeof(string),
        typeof(UserControl1));

For details see Custom Dependency Properties.

  • Related