Binding with Datatemplate member - c#

I have a data template like this
public class DefaultDataTemplate : DataTemplate
{
public string Name
{
get;
set;
}
}
and I am using in xaml like this
<!-- Default DataTemplate -->
<DataTemplate x:Key="DefaultDataTemplate">
<Grid Margin="4" MinHeight="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</Grid>
</DataTemplate>
I want to do binding with the "Name" Property of my datatemplate ,but right now its binded to my List view item's property named "Name".Can anybody help for the correct way or syntax

The DataContext for a DataTemplate is the DataObject it is templating, you will have to bind back to the DataTemplate or in this case DefaultDataTemplate to access the property.
Try:
Text="{Binding Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataTemplate}}}
or
Text="{Binding Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type myNamespace:DefaultDataTemplate }}}

You are not using the template, you just gave the template the same key name as the class.
Also, the custom data template should have dependency properties to bind to.
Do you actually mean to do this:
<ListBox ItemsSource="{Binding Persons}">
<ListBox.DataTemplate>
<DataTemplate >
<Grid Margin="4" MinHeight="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Name" FontWeight="Bold" />
<TextBox Margin="8,0" Grid.Column="1" Text="{Binding Name}" />
</Grid>
</DataTemplate>
</ListBox.DataTemplate>
</ListBox>
Or perhaps
<Window.Resources>
<DataTemplate x:Key="DefaultDataTemplate">
<Grid Margin="4" MinHeight="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Name" FontWeight="Bold" />
<TextBox Margin="8,0" Grid.Column="1" Text="{Binding Name}" />
</Grid>
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding Persons}" DataTemplate="{StaticResource DefaultDataTemplate}"/>
Assuming the Person class has a property Name and the Persons property is an Observable<Person>

Related

WPF DataTemplate - Access Property of Parent object

I am customizing the presentation using the HeaderTemplate of a UI item. I would like to access a property of the parent item in the DataTemplate:
<dxa:AccordionItem Header="{Binding SelectedComponents.Count}" Tag="Test" HighlightOnHover="False" HighlightOnPress="False" Margin="0,0,13,0">
<dxa:AccordionItem.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding RelativeSource=Tag}" VerticalAlignment="Center" />
<TextBlock Text="{Binding}" Grid.Column="2" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Rectangle Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Center" Fill="DimGray" Height="1"/>
</Grid>
</DataTemplate>
</dxa:AccordionItem.HeaderTemplate>
</dxa:AccordionItem>
Basically, I would like to display the Tag property in the DataTemplate.
I have tried:
Text="{Binding RelativeSource=Tag}"
Text="{Binding Path=Tag}"
Text="{Binding ElementName=Tag}"
but nothing seems to work.
I managed to obtain the neccessary binding using the following method:
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dxa:AccordionItem}}, Path=Tag}"

How to bind Observablecollection<T> with combobox in wpf

I am trying to bind Observablecollection<T> with ComboBox. ComboBox having Datatemplete
<ComboBox Width="150" Margin="20,0,0,5" Name="cbSelection" Height="20"
BorderThickness="2" BorderBrush="Black"
SelectedIndex="0" DataContext="{Binding AdComboBox}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding XPath=LOC, Mode=OneWay}" Margin="5,0,5,0"/>
<TextBlock Grid.Column="1" Text="{Binding XPath=PUB, Mode=OneWay}" Margin="0,0,5,0"/>
<TextBlock Grid.Column="2" Text="{Binding XPath=EDI, Mode=OneWay}" Margin="0,0,5,0"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
but not get the data in ComboBox
what going wrong
thanks in advance
Use the ItemsSource of the ComboBox to point to the ObservableCollection<T>. Also: Use Path, not XPath which is used for binding to XML documents.
<ComboBox Width="150" Margin="20,0,0,5" Name="cbSelection" Height="20"
BorderThickness="2" BorderBrush="Black"
ItemsSource="{Binding AdComboBox}"
SelectedIndex="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding Path=LOC, Mode=OneWay}"
Margin="5,0,5,0"/>
<TextBlock Grid.Column="1"
Text="{Binding Path=PUB, Mode=OneWay}"
Margin="0,0,5,0"/>
<TextBlock Grid.Column="2"
Text="{Binding Path=EDI, Mode=OneWay}"
Margin="0,0,5,0"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Side note: you might want to rename the collection to something more functional instead of AdComboBox. E.g., Ads Because it is not a ComboBox but it is a collection of Ads(?)

.NET 4.x WPF ComboBox Databinding SelectedIndex not working

I'm updating my project from .NET Framework 3.5 to .NET Framework 4.5.1. Everything works, except my databinding to a ComboBox. The ComboBox is part of a Itemscontrol. The XAML code:
<ItemsControl x:Name="AfmetingenLijst" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" BorderThickness="0" VerticalContentAlignment="Bottom" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Lengte}" Tag="{Binding LID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="1" Text="{Binding Breedte}" Tag="{Binding BID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="2" Text="{Binding Hoogte}" Tag="{Binding HID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="3" Text="{Binding Naam}" Margin="5,5,5,5" />
<ComboBox Grid.Column="4" ItemsSource="{Binding Path=items}" SelectedIndex="{Binding geselecteerdProduct}" SelectedValuePath="Code" DisplayMemberPath = "Naam" SelectionChanged="UpdateList" Height="25" HorizontalAlignment="Stretch" VerticalAlignment="Center"></ComboBox>
<Button Tag="{Binding ID}" Grid.Column="5" Margin="5,5,5,5" Content="{Binding Title}" Click="Afmeting_handler" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In C# a list is filled with the databinding values:
afm = new List<Afmeting>();
if (afm.Count == 0)
{
afm.Add(new Afmeting() { ID = "+", LID = "L+", BID = "B+", HID = "H+", Title = "+", items = items });
afm[afm.Count - 1].geselecteerdProduct = 0;
afmetingen_counter++;
}
AfmetingenLijst.ItemsSource = afm;
The items in the ComboBox exists, I can select them by mouse. But by default SelectedIndex = -1. But in the list "geselecteerdProduct" (the databinding to SelectedIndex) is set to 0.
In .NET 3.5 it is working perfect, but in 4.x SelectedIndex and the value in "afm" is automatically set to -1.
Items is not empty, there are +- 5 items in the list.
Can someone help me?
I think this is a bug for WPF.
When ComboBox is nested in ItemsControl, and set SelectedIndex and SelectedValuePath at the same time, ComboBox's OnSelectionChanged will be fired tiwce at initialize, but SelectionChanged only once.
WPF ComboBox SelectedIndex debug:
To solve the problem is simple, just remove SelectedValuePath from the ComboBox.
XAML:
<ItemsControl x:Name="AfmetingenLijst" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" BorderThickness="0" VerticalContentAlignment="Bottom" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,5,5,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Lengte}" Tag="{Binding LID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="1" Text="{Binding Breedte}" Tag="{Binding BID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="2" Text="{Binding Hoogte}" Tag="{Binding HID}" Margin="5,5,5,5" TextChanged="UpdateList"/>
<TextBox Grid.Column="3" Text="{Binding Naam}" Margin="5,5,5,5" />
<ComboBox Grid.Column="4"
ItemsSource="{Binding Path=items}"
SelectedIndex="{Binding geselecteerdProduct}"
DisplayMemberPath = "Naam"
SelectionChanged="UpdateList"
Height="25"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
</ComboBox>
<Button Tag="{Binding ID}" Grid.Column="5" Margin="5,5,5,5" Content="{Binding Title}" Click="Afmeting_handler" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Controls vertical alignment with grid on the left and right

I have a custom listbox with a label and a checkbox in each row. I would like to have the label on the far left and the checkbox on the far right.
approach:
<ListBox x:Name="lbFieldsreq" HorizontalAlignment="Left" Height="100" Margin="513,232,0,0" VerticalAlignment="Top" Width="100">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding name, Mode=OneWay}" Grid.Column="0" HorizontalAlignment="Left" />
<Label Grid.Column="1" HorizontalAlignment="Center" /> <!--Empty column -->
<CheckBox IsChecked="{Binding ticked ,Mode=OneWay}" Grid.Column="2" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
current look:
Thx
Your XAML is mostly fine. All you really need to do is to set the ListBox.HorizontalContentAlignment property to "Stretch". This basically forces each item in the collection to stretch to fill with entire Width of the related ListBoxItem. However, you could improve this further by setting the Grid.IsSharedSizeScope Attached Property to True. Setting this in conjunction with the SharedSizeGroup property enables us to ensure that the column Widths of each column of the DataTemplate are the same. Try this:
<ListBox x:Name="lbFieldsreq" HorizontalAlignment="Left" Height="100" ItemsSource="{Binding Items}" VerticalAlignment="Top" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid ShowGridLines="True" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumn" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="CheckBoxColumn" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Grid.Column="0" HorizontalAlignment="Left" />
<!--Empty column -->
<Label Grid.Column="1" HorizontalAlignment="Center" />
<CheckBox Grid.Column="2" IsChecked="{Binding ticked, Mode=OneWay}" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How do I have ListBox items fill the entire space?

Hi I see there have been many questions about ListBox and filling the entire space for the DataTemplate but I still cannot get anything to work. What I have is a ListBox and the DataTemplate has a UserControl. How do I get my UserControl to stretch the data to fill the space?
MainWindow XAML snippet:
<ListBox x:Name="ConfiguredItemsList">
<ListBox.ItemTemplate>
<DataTemplate>
<local:ConfiguredItem DataContext="{Binding}" HorizontalContentAlignment="Stretch" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
UserControl XAML snippet:
<UserControl.Resources>
<local:ImagePathConverter x:Key="ImagePathConverter"/>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="75" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" x:Name="NameLabel" Text="Name:" />
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="tbName" Text="{Binding Path=Name}" />
<TextBlock Grid.Row="1" Grid.Column="0" x:Name="DescriptionLabel" Text="Description: " />
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="Description" Text="{Binding Path=Description}" />
<TextBlock Grid.Row="2" Grid.Column="0" x:Name="TimeLabel" Text="Time:" />
<TextBlock Grid.Row="2" Grid.Column="1" x:Name="Time" Text="{Binding Path=ChangeTime, StringFormat={}{0:h:mm tt}}" />
</Grid>
<Border Grid.Column="1" BorderThickness="1" BorderBrush="Black">
<Image Source="{Binding Path=WallpaperInfo, Converter={StaticResource ImagePathConverter}}" />
</Border>
</Grid>
Have you tried to set HorizontalContentAlignment to stretch on list box level?
<ListBox x:Name="ConfiguredItemsList" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<local:ConfiguredItem DataContext="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Note: I have set HorizontalContentAlignment property of ListBox instead of Item.

Categories

Resources