(Wpf, .Net4)
Hey, When I use a Data Template with DataType (and no key) it only applies in the constructor. (I must use it that way because I have two different type). The thing is, it works on .net 3.5, and now I need to upgrade to .net 4. (I played with the properties of the project and saw that it's working on 3.5) This is the entire code (except for the default App.xaml):
MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1" x:Name="me"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition />
</Grid.RowDefinitions>
<ToolBar ItemsSource="{Binding ElementName=me, Path=Items}">
<ToolBar.Resources>
<DataTemplate DataType="{x:Type local:Class1}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ToolBar.Resources>
</ToolBar>
<StackPanel Grid.Row="1">
<Button Content="1" Click="Button_Click"/>
</StackPanel>
</Grid>
</Window>
MainWindow.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
Items = new ObservableCollection<Class1>();
Items.Add(new Class1() { Title = "1" });
InitializeComponent();
}
public ObservableCollection<Class1> Items { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Add(new Class1() { Title = (Items.Count + 1).ToString() });
}
}
public class Class1
{
public string Title { get; set; }
}
}
The button adds items dynamicly, we can see the first one shows its title, and the dynamicly added items doesn't have a template applied. What can I do? thanks.
Apparently after rendering Toolbar doesn`t use default Class1 template anymore. There are several solutions that can work here depending on requirements.
1) Define DataTemplate in App.xaml:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<DataTemplate DataType="{x:Type TestWPF:Class1}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Assuming you have some other resource dictionaries there as well. If not, DataTemplate can be placed right into Application.Resources without all that Dictionary stuff.
2) When an object doesn`t have a default template it just uses its ToString method to represent itself visually. So your Class1 (and others) can override ToString:
public class Class1
{
public string Title { get; set; }
public override string ToString()
{
return Title;
}
}
3) Standard WPF approach for ItemControls - have ItemTemplate:
<ToolBar ItemsSource="{Binding ElementName=me, Path=Items}">
<ToolBar.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</ToolBar.ItemTemplate>
</ToolBar>
But you said that there are several types that should have templates so for this to work you will have to implement ItemTemplateSelector for ToolBar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With