DataTemplating Binding not correct - wpf

I have the following code which Binds to properties within a ToolTip DataTemplate:
<Window x:Class="WpfConcepts.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
xmlns:telerikData="clr-namespace:Telerik.Windows.Data;assembly=Telerik.Windows.Data"
xmlns:telerikGridview="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView"
xmlns:telerikInput="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input" Width="200" Height="480">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<telerikGrid:RadGridView Grid.Column="0" Grid.Row="0" x:Name="FXRateGridView" ItemsSource="{Binding CarList}" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible" ColumnWidth="*" MinColumnWidth="50" AutoGenerateColumns="False">
<telerikGrid:RadGridView.Columns>
<telerikGrid:GridViewDataColumn>
<telerikGrid:GridViewDataColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}">
<TextBlock.ToolTip>
<ToolTip>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Colour}"/>
</StackPanel>
</DataTemplate>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</telerikGrid:GridViewDataColumn.CellTemplate>
</telerikGrid:GridViewDataColumn>
</telerikGrid:RadGridView.Columns>
</telerikGrid:RadGridView>
</Grid>
</Window>
The tooltip displays as "System.Window.DataTemplate" which is not the desired effect since I'm expecting the Colour property value instead.
If I don't use a datatemplate within the ToolTip then I get the correct value, I assume my usage DataTemplate is not correct.

If you want to reuse the toolTip create an instance of it in Window Resources and use it wherever you need, using StaticResource like this -
<Window>
....
<Window.Resources>
<ToolTip x:Key="ColourToolTip">
<StackPanel>
<TextBlock Text="{Binding Path=Colour}"/>
</StackPanel>
</ToolTip>
</Window.Resources>
Use this resource in your template like this-
<TextBlock Text="{Binding Name}"
ToolTip="{StaticResource ColourToolTip}">

There is no need for DataTemplate, just use the following:
<ToolTip>
<TextBlock Text="{Binding Path=Colour}"/>
</ToolTip>

Related

How can I set the binding for a control's property (which is inside DataTemplate and UserControl) to use the ItemSource's given property?

I would like to make a UserControl which have a DataTemplate, and inside that DataTemplate there are controls. I would like to bind to those nested (inside the DataTemplate) controls' properties so I can set them when I reuse this UserControl. The nested controls will use the ItemSource's properties but the property names of the ItemSource's properties could be different.
The UserControl:
<UserControl x:Class="ContextMenu.BaseFilterUserControl"
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"
x:Name="Self">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10"
Text="Owners" />
<Button Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="10"
Click="FilteButtonClicked"
Width="40"
Height="40"
x:Name="FilterButton">
<Popup x:Name="FilterBoxPopup"
PlacementTarget="{Binding ElementName=FilterButton}"
Placement="Bottom"
StaysOpen="False">
<Border BorderBrush="Black"
Background="White"
Margin="2">
<ListView ItemsSource="{Binding ElementName=Self, Path=FilterList}"
x:Name="FilterListView"
Height="300"
Width="150">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<CheckBox IsChecked="{Binding IsChecked}" />-->
<!--<TextBlock Text="{Binding Name}" />-->
<!--This is where I don't know how to properly bind eg. the above control, things I tried:-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=Self, Path=DataContext.FilterElementName}" />-->
<!--<TextBlock Text="{Binding ElementName=FilterListView, Path=DataContext.FilterElementName}" />-->
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Border>
</Popup>
</Button>
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10"
Text="{Binding ElementName=Self, Path=SelectedNames}" />
</Grid>
</UserControl>
This how the UserControl is used, the FilterElementName="Name" is what I would like to set, depending on the list binded with FilterList list:
<local:BaseFilterUserControl FilterList="{Binding Owners}"
FilterElementName="Name"
SelectedNames="{Binding SelectedNames}"/>
In this case the Owners is a simple IReadOnlyList of an Owner class. The Owner class has a string Name property. But I will use this UserControl again with different list eg. where I would like to use the Versions list's Release property (for the TextBlock inside the UserControl):
<local:BaseFilterUserControl FilterList="{Binding Versions}"
FilterElementName="Release"
SelectedNames="{Binding SelectedReleases}"/>
The ListView is properly populated with items, so the FilterList DependencyProperty is working. But the nested controls are only working when I hard code the bindings:
<TextBlock Text="{Binding Name}" />
For this to work you would need to bind the Path-property of your TextBlocks Text-Binding to the FilterElementName property of your UserControl. Unfortunately the Path property of the Binding class is not a DependencyProperty and therefore not bindable.
One way to to achieve your goal would be to use the DisplayMemberPath property of the ListView, which is bindable:
<ListView x:Name="FilterListView"
Width="150"
Height="300"
ItemsSource="{Binding ElementName=Self, Path=FilterList}"
DisplayMemberPath="{Binding ElementName=self, Path=FilterElementName}"/>
If this approach does not work because you need to specify a more complex ItemTemplate, another way would be create a property of type DataTemplate in your UserControl, use that as ItemTemplate in the ListView and specify it from outside like so:
<local:BaseFilterUserControl FilterList="{Binding Versions}"
SelectedNames="{Binding SelectedReleases}">
<local:BaseFilterUserControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Release}" />
</DataTemplate>
</local:BaseFilterUserControl.ItemTemplate>
</local:BaseFilterUserControl>

How to add images to UserControl menu in Wpf

enter code here<Window
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:EPOS.Desktop.View"
xmlns:vm="clr-namespace:EPOS.Desktop.ViewModel"
xmlns:UserControls="clr-namespace:EPOS.Desktop.UserControls"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui" xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar" x:Class="EPOS.Desktop.View.MainSaleUI"
mc:Ignorable="d"
Title="MainSaleUI"
Width="1046" Height="500" Left="500" Top="500"
Background="SkyBlue"
WindowStartupLocation="CenterScreen"
>
<Window.Resources>
<DataTemplate DataType="{x:Type vm:QeueOrdersViewViewModel}">
<UserControls:QeueOrders />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:TillViewModel}">
<UserControls:TillUC/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SettingViewModel}">
<UserControls:Settings/>
</DataTemplate>
</Window.Resources>
<Grid Margin="0,67,65,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="ListBoxMenu"
Grid.Column="0" Margin="5"
ItemsSource="{Binding Settings}"
SelectedIndex="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Padding="10"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Grid.Column="1" Margin="5,5,10,5" BorderBrush="#FF7F9DB9" BorderThickness="1">
<ContentControl Content="{Binding ElementName=ListBoxMenu, Path=SelectedItem}" Margin="0,0,225,0"/>
</Border>
</Grid>
Blockquote
How to add images to User-control menu in Wpf. These are dynamic menus. Is there way to add images to every text?
I'm not sure about what you exactly want... assuming that you want to display some image right after /before the text on your listbox you can add an image property in your "settings" class (Binding of your Listbox's Itemsource) and change your listbox's datatemplate content with something like this :
<StackPanel>
<TextBlock Text="{Binding Name}" Padding="10"/>
<Image Source="{Binding Image }" />
</StackPanel>

user control inside tabitem does not change values

I have a TabContorl and I am adding tabitem dynamically. I have bind datatemplate to some viewmodel and view is loaded as defined in datatemplate.
<DataTemplate DataType="{x:Type viewmodels:ItemViewModel}">
<views:CustomerOrderView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:InvoiceGeneratorViewModel}">
<views:InvoiceGenerator/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OrderDetailsViewModel}">
<views:OrderDetailsView/>
</DataTemplate>
if i use controls directly in customerorderview then it works fine. It means if i switch the tab all values are loaded accordingly but does not work properly when if i use another usercontrol insite customerview user control. I have created once user control have one textbox, button and a popup contorl. When i click on button the popup opens and remains even if swich the tab. If textbox value is change the value is also changed for all tabs. It looks one view is serving all the tabs. I could not understand how to handle it.
Below is the user control which i am using inside customer
<UserControl x:Class="OrderManagement.Views.ProductSelectionView"
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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtProduct" Grid.Row="0" Grid.Column="0"/>
<Button x:Name="btnSearch" Content="S" Click="OnSearchClick" Grid.Row="0" Grid.Column="1" Margin="5"/>
<Popup x:Name="popup" PlacementTarget="{Binding ElementName=btnSearch}" Placement="Bottom"
Width="300" Height="300" Margin="5">
<Border BorderBrush="Black" BorderThickness="2" Background="AliceBlue">
<Grid >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False" Grid.Row="0" Grid.ColumnSpan="2"
IsReadOnly="False" CanUserAddRows="False" CanUserDeleteRows="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding IsChecked}" IsReadOnly="False"/>
<DataGridTextColumn Header="Product Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Quantity In Stock" Binding="{Binding QuantityInStock}"/>
</DataGrid.Columns>
</DataGrid>
<WrapPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right">
<Button Content="OK" Click="OnOKClick" Width="80"/>
<Button Content="Cancel" Click="OnCancelClick" Width="80" Margin="20,0,0,0"/>
</WrapPanel>
</Grid>
</Border>
</Popup>
</Grid>
</UserControl>
Tabcontrol virtualize the data as per its datacontext but popup and text value in productselection control remains the same for all tabs. opens the popup but it remains for all the tab.
Let me know if how it can be done or what is the mistake i am doing

Overriding Style of WPF TreeView Items

I am using the awesome MahAppsMetro WPF control suite. I have a tree view that loads the file system. I also want to display images in the TreeViewItems so I have overridden the metro tree style as follows
<UserControl x:Class="GDE.Tree.TreeView"
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:Caliburn="http://www.caliburnproject.org"
xmlns:Metro="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<UserControl.Resources>
<HierarchicalDataTemplate x:Key="TreeTemplate" ItemsSource="{Binding Path=Children}"/>
</UserControl.Resources>
<!--TreeView-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
Margin="5"
IsReadOnly="True"
Text="{Binding SelectedPath, Mode=TwoWay}"/>
<TreeView Grid.Row="1"
Margin="5"
ItemsSource="{Binding RootChildren}"
ItemTemplate="{StaticResource TreeTemplate}">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}"
BasedOn="{StaticResource MetroTreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="img"
Width="16"
Height="16"
Stretch="Fill"
Source="{Binding Path=Icon, Mode=OneTime}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding DisplayName, Mode=OneTime}"
Margin="5,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
</Grid>
</UserControl>
But this does not seem to work as intended and I can't figure out why. From this XAML, I get no binding errors and the visuals look like:
I have gone more extensive with the XAML mark up but I am getting the exact same visuals. How can I change the above XAML to give me the Image/TextBlocks as well as the MahApps look and feel?
Thanks for your time.
To sum up comments instead of changing Style you need to move StackPanel from DataTemplate directly into HierarchicalDataTemplate as at the moment used template has no content:
<HierarchicalDataTemplate x:Key="TreeTemplate" ItemsSource="{Binding Path=Children}">
<StackPanel Orientation="Horizontal">
<Image Name="img" ... />
<TextBlock Text="{Binding DisplayName, Mode=OneTime}" ... />
</StackPanel>
</HierarchicalDataTemplate>

Binding nested control using MVVM pattern

I have a problem with binding nested control with my MVVM pattern. This is my XAML code:
<ItemsControl Grid.Column="1" ItemsSource="{Binding NotificationContacts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:Expander>
<toolkit:Expander.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ContactName}" Grid.Column="0" VerticalAlignment="Center"></TextBlock>
<Image Source="Images/answer_ok.png" Grid.Column="1" Margin="15,0,15,0" Width="27" Height="27"></Image>
</Grid>
</toolkit:Expander.Header>
<toolkit:Expander.Content>
<ListBox Margin="30,10,0,10" ItemsSource="{Binding NotificationContacts.Messages">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MessageName}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</toolkit:Expander.Content>
</toolkit:Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The problem is, that the listbox control located in ExpanderControl Data Template is not being data bound.
Listbox control is populated by EntityCollection named 'Messages' which is contained in parent object 'NotificationContacts' that ItemsControl is databound with...
Does anyone know how to resolve this issue ?
Thanks in advance !!!
Did you try this:
<ItemsControl Grid.Column="1" ItemsSource="{Binding NotificationContacts}">
......
<ListBox Margin="30,10,0,10" ItemsSource="{Binding Messages}">
.....
<TextBlock Text="{Binding MessageName}"></TextBlock>
If I remember it right, when you are "inside" ItemContol, binding context is set to NotificationContacts. So use just "{Binding Messages}" could be fine.
And by the way, you are missing curly bracket on the line:
<ListBox Margin="30,10,0,10" ItemsSource="{Binding NotificationContacts.Messages">
Call ItemsControl f.i. "ic" and use next binding in ListBox
<ItemsControl x:Name="ic" Grid.Column="1" ItemsSource="{Binding NotificationContacts}">
...
<ListBox Margin="30,10,0,10" ItemsSource="{Binding ElementName=ic, Path=DataContext.Messages}">

Resources