I have the following UserControl:
<UserControl x:Class="ConcreteAnalyzer.Views.CenterSectionPropertiesView"
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:c="clr-namespace:ConcreteAnalyzer.Converters"
xmlns:local="clr-namespace:ConcreteAnalyzer.Views"
xmlns:vm="clr-namespace:ConcreteAnalyzer.ViewModels.CenterSection"
mc:Ignorable="d">
<UserControl.Resources >
<c:DebugConverter x:Key="DebugConverter"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="8"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TreeView Grid.Row="0" x:Name="CenterSectionTree">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:PanViewModel}">
<TreeViewItem Header="Pan"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeViewItem Header="Center Section" DataContext="{Binding CenterSection}">
<TreeViewItem Header="Front" DataContext="{Binding XPositive}" ItemsSource="{Binding Pans, Converter={StaticResource DebugConverter}}"/>
<TreeViewItem Header="Back" DataContext="{Binding XNegative}" ItemsSource="{Binding Pans}"/>
<TreeViewItem Header="Left" DataContext="{Binding YPositive}" ItemsSource="{Binding Pans}"/>
<TreeViewItem Header="Rigth" DataContext="{Binding YNegative}" ItemsSource="{Binding Pans}"/>
</TreeViewItem>
</TreeView>
<GridSplitter Grid.Row="1" Height="8" ResizeDirection="Rows" HorizontalAlignment="Stretch" ResizeBehavior="PreviousAndNext">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Content="⁞" Background="Transparent" Foreground="White"/>
<Rectangle Fill="{StaticResource TurqoiseBrush}"/>
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter >
<ContentControl Content="{Binding SelectedItem.DataContext, ElementName=CenterSectionTree, Converter={StaticResource DebugConverter}}" Grid.Row="2">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type vm:CenterSectionViewModel}">
<TextBlock Text="Center Section"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:WallViewModel}">
<TextBlock Text="Wall"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:PanViewModel}">
<TextBlock Text="Pan"/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
This works just fine for the Treeview items that are hard-coded but if I select one of the pans, the ElementBinding does not connect. I could change the treeview to use HiearchicalDataTemplate, but to do that I think I have to create dummy collections to bind to at each level as well as add a property to the walls so that I can tell which wall is which. Creating all that dummy info just to make the treeview work has some code smell to me.
Any thoughts on the best way to get this to work?
edit:
The reason it's not working is because when the hard-coded treeview items are selected the databinding points at the TreeViewItem itself and so I was binding to the SelectedItem.DataContext. When you select a Pan, the SelectedItem is the PanViewModel, not the TreeViewItem.
If I Try simply binding to the SelectedItem, the hard-coded TreeViewItems will not work because it tries to inject the TreeViewItem itself into a ContentControl, which throws an exception.
Binding to the SelectedItem.DataContext won't work because the PanViewModel doesn't have a DataContext. I'm still not seeing an elegant solution to this.
Related
So I'm defining a DataTemplate in the UserControl.Resources like so:
<DataTemplate x:Key="Impact">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Impact:" />
<ComboBox Grid.Column="1"
ItemsSource="{Binding Impacts}">
</ComboBox>
</Grid>
</DataTemplate>
I then have an ItemsControl define like so in the visual tree:
<ItemsControl ItemsSource="{Binding Path=ViewModelsList}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type ui:FirstViewModel}">
<ContentControl ContentTemplate="{StaticResource Impact}"></ContentControl>
</DataTemplate>
<DataTemplate DataType="{x:Type ui:SecondViewModel}">
<ContentControl ContentTemplate="{StaticResource Impact}"></ContentControl>
...
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
Is there a way to relate that {Binding Impacts} in the resources to the respective ViewModel type defined in DataTemplate's DataType?
Maybe there is a way to pass the DataType to the ContentControl?
Add this to your ContentControls:
Content="{Binding}"
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>
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>
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>
I have a XML file which has maximum three levels of child elements so i need to bind the file with TreeView in WPF for XBAP App Dynamically.
Do we need to use Hierarchical template or is there any other way to get easy binding..
for example:
<TriggerList>
<Trigger>
<TriggerName>trig1</TriggerName>
<TriggerSource>manual</TriggerSource>
<TriggerInfo>
<Alaramid>2312</Alaramid>
<Area>area1</Area>
<ToolType>OLF121</ToolType>
</TriggerInfo>
</Trigger>
</TriggerList>
I want to make this in tree view through Dynamic Binding ..
Answer is :
<UserControl x:Class="XTREAMSUI.UserControls.ExecutionList"
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:mvvm="clr-namespace:MvvmFoundation.Wpf;assembly=MvvmFoundation.Wpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="230">
<UserControl.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding RFCNameList}" x:Key="RFCTemplate">
<TextBlock Text="{Binding RFCName}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding RFCNameList}" x:Key="TriggerIDTemplate" ItemTemplate="{StaticResource RFCTemplate}">
<TextBlock Text="{Binding TriggerID}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TriggerIDList}" x:Key="TriggerSourceTemplate" ItemTemplate="{StaticResource TriggerIDTemplate}">
<TextBlock Text="{Binding TriggerSource}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TriggerList}" x:Key="TriggerTemplate" ItemTemplate="{StaticResource TriggerSourceTemplate}">
<TextBlock Text="{Binding HostMachineName}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</UserControl.Resources>
<Grid Name="gridExecutionlst" IsEnabled="{Binding IsExecutionListEnabled, Mode=TwoWay}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--<TreeView Grid.Row="0" Name="treeviewExecutionList" Height="400" Width="200" ItemsSource="{Binding TriggerListXML}" ItemTemplate="{StaticResource dataTemplateExecutionList}"></TreeView>-->
<TreeView Name="treeviewExecutionList" Height="450" Width="230" FontWeight="Normal" ItemsSource="{Binding Path=TriggerList,Mode=TwoWay}" ItemTemplate="{StaticResource TriggerTemplate}">
<mvvm:CommandBehaviorCollection.Behaviors>
<mvvm:BehaviorBinding Command="{Binding ListBoxCommand}" Event="MouseDoubleClick" CommandParameter="{Binding ElementName=treeviewExecutionList, Path=SelectedItem}"/>
</mvvm:CommandBehaviorCollection.Behaviors>
</TreeView>
</Grid>
</UserControl>
Answer is :
`
<HierarchicalDataTemplate ItemsSource="{Binding RFCNameList}" x:Key="RFCTemplate">
<TextBlock Text="{Binding RFCName}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding RFCNameList}" x:Key="TriggerIDTemplate" ItemTemplate="{StaticResource RFCTemplate}">
<TextBlock Text="{Binding TriggerID}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TriggerIDList}" x:Key="TriggerSourceTemplate" ItemTemplate="{StaticResource TriggerIDTemplate}">
<TextBlock Text="{Binding TriggerSource}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TriggerList}" x:Key="TriggerTemplate" ItemTemplate="{StaticResource TriggerSourceTemplate}">
<TextBlock Text="{Binding HostMachineName}" IsEnabled="False"/>
</HierarchicalDataTemplate>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
<TreeView Name="treeviewExecutionList" Height="450" Width="230" FontWeight="Normal" ItemsSource="{Binding Path=TriggerList,Mode=TwoWay}" ItemTemplate="{StaticResource TriggerTemplate}">
<mvvm:CommandBehaviorCollection.Behaviors>
<mvvm:BehaviorBinding Command="{Binding ListBoxCommand}" Event="MouseDoubleClick" CommandParameter="{Binding ElementName=treeviewExecutionList, Path=SelectedItem}"/>
</mvvm:CommandBehaviorCollection.Behaviors>
</TreeView>