Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

Item DataTemplate property in a custom UserControl

$
0
0

Consider following user control:

UserControl1.xaml

<UserControl x:Class="WpfApplication5.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"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300"><ListBox ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=UserControl}}"><ListBox.ItemTemplate><DataTemplate><Button ContentTemplate="{Binding ItemContentTemplate, RelativeSource={RelativeSource AncestorType=UserControl}}" /></DataTemplate></ListBox.ItemTemplate></ListBox></UserControl>

UserControl1.xaml.cs:

using System.Collections; using System.ComponentModel; using System.Windows; namespace WpfApplication5 { public partial class UserControl1 : INotifyPropertyChanged { public UserControl1() { InitializeComponent(); }

private DataTemplate _itemContentTemplate; public DataTemplate ItemContentTemplate { get { return _itemContentTemplate; } set { _itemContentTemplate = value; OnPropertyChanged("ItemContentTemplate"); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof (IEnumerable), typeof (UserControl1), new PropertyMetadata(default(IEnumerable))); public IEnumerable ItemsSource { get { return (IEnumerable) GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } }

And it's usage:

MainWindow.xaml

<Window x:Class="WpfApplication5.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfApplication5="clr-namespace:WpfApplication5" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"><Window.Resources><DataTemplate x:Key="dataTemplate"><Label Content="{Binding DataContext.Name1, RelativeSource={RelativeSource AncestorType=ListBoxItem}}"></Label></DataTemplate></Window.Resources>

<Grid><wpfApplication5:UserControl1 ItemsSource="{Binding Items}" ItemContentTemplate="{StaticResource dataTemplate}"></wpfApplication5:UserControl1></Grid></Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;

namespace WpfApplication5
{
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			InitializeComponent();
		}

		public List<Item1> _items = new List<Item1>(){new Item1(){Name1 = "Item 1"}, new Item1(){Name1 = "Item 2"}, new Item1(){Name1 = "Item 3"}};
		public List<Item1> Items
		{
			get { return _items; }
		}
	}

	public class Item1
	{
		public string Name1 { get; set; }
	}
}
Output, all works fine:


Pay attention on following code in MainWindow.xaml: 
, RelativeSource={RelativeSource AncestorType=Button}

I set binding source for the Label. Without this code UserControl1 does not work correctly. Let us usesecond version of MainWindow.xaml:

<Window x:Class="WpfApplication5.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfApplication5="clr-namespace:WpfApplication5" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"><Window.Resources><DataTemplate x:Key="dataTemplate"><Label Content="{Binding Name1}"></Label></DataTemplate></Window.Resources>

<Grid><wpfApplication5:UserControl1 ItemsSource="{Binding Items}" ItemContentTemplate="{StaticResource dataTemplate}"></wpfApplication5:UserControl1></Grid></Window>

Output will be:

Question: how to change UserControl1 so that to eliminate necessity of setting binding source for the Label in the template in order tosecond version of MainWindow.xaml become valid usage of UserControl1? I want get answer on this question because of I think it is wrong to violate incapsulation of UserConrol1. We should be in lack of knowledge what container is used in UserControl1 to displying items: Button on something else. 

See related thread: https://social.msdn.microsoft.com/Forums/vstudio/en-US/ca1da6ba-80da-4947-824a-af667961cc4b/datatemplate-property-in-a-custom-usercontrol?forum=wpf





Viewing all articles
Browse latest Browse all 18858

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>