I have a Datagrid which has a DataGridTemplateColumn containing a ListView whose Itemsource is bound to an array of string.
Within that ListView I have defined an ItemTemplate as I want the Foreground of each item in the list to be dependant on condition - so that's applied to a TextBlock.
I want a tooltip to display when each item in the ListView is hovered over, so I have a Tooltip defined in that TextBlock
What I'm trying to do is have that Tooltip display the title/detail about a specific item by using a converter (to get the index of the item in a different list).
For this I need the Tooltip to know the ListView item but I can't seem to get that to work. The TextBlock itself retrieves it using Path=., I have tried naming the TextBlock ListItem and retrieving it as ElementName to no avail - the result is just empty string.
Here's the relevant xaml (with formatting properties removed).
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="ListItem" Text="{Binding Path=.}" Foreground="{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource ConvertItemToColour}}">
<TextBlock.ToolTip>
<ToolTip>
<StackPanel Orientation="Vertical">
<Label>
<TextBlock Text="{Binding ElementName=ListItem, Path=Text, Converter={StaticResource ConvertItemToTitle}}"/> <!-- Item Title -->
</Label>
<Label>
<TextBlock/> <!-- Item Description -->
</Label>
</StackPanel>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
ToolTip, like Popup, is not part of the main visual tree so neither ElementName nor RelativeSource binding will work beyond ToolTip but DataContext inside ToolTip should still be the same as for ListViewItem
<ToolTip>
<StackPanel Orientation="Vertical">
<Label>
<TextBlock Text="{Binding Path=., Converter={StaticResource ConvertItemToTitle}}"/>
</Label>
</StackPanel>
</ToolTip>
Text="{Binding Path=.}" should give you same result inside ToolTip as in DataTemplate
Related
how can i bind an element inside of a template to a property of its parent like:
<Button Tag="rofl">
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="{ HERE I WANT TO BIND TO THE BUTTONS TAG }"/>
</DataTemplate>
</Button.ContentTemplate>
</Button>
Is that possible?
In addition to #Pedro Lamas's answer you can also perform this by the following way:
<Button x:Name="ButtonTemplate" Tag="rofl">
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Tag, ElementName=ButtonTemplate}"/>
</DataTemplate>
</Button.ContentTemplate>
</Button>
You define a name for your control and access it's property in it's DataTemplate thanks to the ElementName feature.
You should be able to use a RelativeSource with the TemplatedParent to do that:
<TextBlock Text="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}"/>
I'm using a Listbox to show multiple items.
The items are grouped. Now I want to edit the header style but the only thing happens is that the text isn't shown anymore.
Thats my xaml:
<ListBox x:Name="lbTreatments" HorizontalAlignment="Left" Height="473" Margin="10,37,0,0" VerticalAlignment="Top" Width="309" FontSize="13">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding subcategoryName}" FontWeight="Bold"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And thats my code to group the items:
ICollectionView view = CollectionViewSource.GetDefaultView(treatmentsCategory);
view.GroupDescriptions.Add(new PropertyGroupDescription("subcategoryName"));
view.SortDescriptions.Add(new SortDescription("subcategoryName", ListSortDirection.Ascending));
lbTreatments.ItemsSource = view;
The items are grouped but the header text is missing. If I delete the Groupstyle from xaml the text will be shown. Can anybode help me please?
MSDN says:
Each group is of type CollectionViewGroup.
The actual data type is CollectionViewGroup which doesn't have a subcategoryName property so the binding will fail. Instead you have to use the Name property, which will already be set to the value from subcategoryName.
As such, use this...
<TextBlock Text="{Binding Name}"/>
...in your header template to get the group name.
I am creating Treeview in wpf.
Each parent item set random foreground color using converter.
I want all its children to set the same color. using only xaml.
Here is part of my code:
<HierarchicalDataTemplate DataType="{x:Type sotc:Category}"
ItemsSource="{Binding Path=NoteList}">
<TextBlock Text="{Binding Path=Name}" Forground="{Binding Path=Name, Convert={StaticResource Converter1}}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type sotc:Note}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
What I wish to do is to set the second treeview item (in the xaml code), Children in HierarchicalData the same forgound color as its parent.
Is there a way to do that?
Thank Ahead,
You can try by using the FindAncestor RelativeSource mode.
Just replace your Note template with this one:
<DataTemplate DataType="{x:Type sotc:Note}">
<TextBlock Text="{Binding Path=Name}"
Foreground="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=2, AncestorType=TreeViewItem}, Path=Header.Name, Converter={StaticResource Converter1}}"/>
</DataTemplate>
I used a DataTemplate, but you can keep using a HierarchicalDataTemplate if you prefer.
I got the following:
<ListView ItemsSource="{Binding Path=Items}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Foreground="{Binding Path=GridTextColor}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The datacontext looks like this:
class{
items = List with items (each row has a name property)
GridTextColor = Brush
}
I bind the listview with all items. Each item contains a name and that name shows up nicely in the listview.
The problem is that i want all items inside the DataTemplate to have the Foreground set to the brush.
With the code above that is not possible since when i am inside the DataTemplate i bind to the items that are sent in.
Question, how can i bind to the "parent datacontext" to get the correct foreground color?
You can use RelativeSource in your binding to get parent's DataContext.
<TextBlock Text="{Binding Path=Name}"
Foreground="{Binding Path=DataContext.GridTextColor,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=ListView}}"/>
Or Set x:Name on ListView and bind using ElementName:
<ListView x:Name="myListView">
....
<TextBlock Text="{Binding Path=Name}"
Foreground="{Binding DataContext.GridTextColor,
ElementName=myListView}" />
....
</ListView>
In my application using DataTemplate mechanism I insert into ListBox item another listbox. But is it possible that when selected one listboxitem in parent listbox, the focus may be on another parent listboxitem's child (see picture)
How to do: if one of child listbox in focus (one item from them selected), then parent listboxitem being selected to? Using binding or templating
<DataTemplate x:Key="NotesListBoxDataTemplate" DataType="Note">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<my:DatePicker Height="25" Name="datePicker1" Width="115" xmlns:my="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
SelectedDate="{Binding LastEdit,
Mode = TwoWay}" />
</StackPanel>
<TextBox Text="{Binding Path=Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<StackPanel Orientation="Horizontal">
<ListBox Name="ImagesListBox" SelectedIndex="{Binding Mode=OneWayToSource, Source={StaticResource progParameters}, Path=SelectedImage, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path=Images}" ItemTemplate="{StaticResource NotesListBoxImagesTemplate}" Style="{StaticResource HorizontalListBox}">
</ListBox>
<StackPanel Orientation="Vertical">
<Button Name="AddImageButon" Content="+" Click="AddImageButon_Click"></Button>
<Button Name="RemoveImageButon" Content="-" Click="RemoveImageButon_Click"></Button>
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
On the parent ListBox set property IsSynchronizedWithCurrentItem to true, then in the inner ListBoxes set the SelectedItem property to "{Binding SelectedItem ElementName=lbParent}".
Consider using a Converter to help you get specific data that is not accessible thru xaml or if you need to do some caculations.
Hope this helps.