How to dynamically change a WPF control's template using a checkbox? - c#

I have an error dialog (shown simplified below).
I display the Report object in a ContentControl to which I have defined a Template simpleErrorTemplate.
There is a CheckBox on the Window that I would like to use to change the template to/from detailedErrorTemplate. What is the best way to achieve this?
<Window x:Class="Core.ErrorDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ControlTemplate x:Key="simpleErrorTemplate">
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="{Binding Message}" />
</ControlTemplate>
<ControlTemplate x:Key="detailedErrorTemplate">
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="{Binding Message}" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="{Binding Details}" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="{Binding StackTrace}" />
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" Template="{StaticResource simpleErrorTemplate}" DataContext="{Binding Report}"/>
<CheckBox Margin="10,0,0,0" Grid.Row="1" x:Name="ChkShowDetails">Show Details</CheckBox>
</Grid>
</Window>

You can use a DataTrigger in the ContentControl Style where you bind to the IsChecked property of the ChkShowDetails CheckBox
<ContentControl Grid.Row="0" DataContext="{Binding Report}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template"
Value="{StaticResource simpleErrorTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ChkShowDetails,
Path=IsChecked}"
Value="True">
<Setter Property="Template"
Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
Update
Complete Xaml example, paste it and try it :)
<Window.Resources>
<ControlTemplate x:Key="simpleErrorTemplate">
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T1" />
</ControlTemplate>
<ControlTemplate x:Key="detailedErrorTemplate">
<StackPanel>
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T2" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T3" />
<TextBox Margin="10,10,10,5" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" Text="T4" />
</StackPanel>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" DataContext="{Binding Report}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template"
Value="{StaticResource simpleErrorTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ChkShowDetails,
Path=IsChecked}"
Value="True">
<Setter Property="Template"
Value="{StaticResource detailedErrorTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<CheckBox Margin="10,0,0,0" Grid.Row="1" x:Name="ChkShowDetails">Show Details</CheckBox>
</Grid>

This Solution is for those who are searching for Template swap.
It is simple hope it helps you. Please point out any mistakes.
Just use this code for changing the Template on checkBox Checked Event.
private void checkBox1_Checked(object sender, RoutedEventArgs e)
{
DataTemplate Temp;
Temp = (DataTemplate)this.FindResource("TemplateYouHaveCreated");
listView1.ItemTemplate = Temp;
}
refer this link for more information
http://developingfor.net/2009/01/09/dynamically-switch-wpf-datatemplate/

Related

How to change Color Inside a Window.Resources C# WPfF

I want to change the color of items inside the Windows.Resources when click a Button.
<Window.Resources>
<DataTemplate x:Key="Listboxcmmt">
<Border>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtbox1" Text="{Binding U_Name}" Foreground="#072D55"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
binding to
<ListBox x:Name="lb_listcmmts" ItemsSource="{Binding Tables[0]}" ItemTemplate="{StaticResource Listboxcmmt}">
<ListBox.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
</Style>
</ListBox.Resources>
</ListBox>
I have little Knowledge about Data Binding, wondering if there is a another way.
private void Btn_clicked (object ...)
{
txtbox1.Foreground = Brushes.White;
}
First, I made a ToggleButton instead of Button.
<ToggleButton x:Name="btn" Grid.Column="1" Content="Change Color"
Width="100" Height="50" Margin="30" VerticalAlignment="Top"/>
And in DataTemplate, you have to use Trigger.
<Window.Resources>
<DataTemplate x:Key="Listboxcmmt">
<Border>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtbox1" Text="{Binding U_Name}" Foreground="#072D55"/>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=btn, Path=IsChecked}" Value="True">
<Setter TargetName="txtbox1" Property="Foreground" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
MainWindow.xaml
<Window x:Class="ListBoxTriggerSample.MainWindow"
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:ListBoxTriggerSample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate x:Key="Listboxcmmt">
<Border >
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtbox1" Text="{Binding U_Name}" Foreground="#072D55"/>
</StackPanel>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=btn, Path=IsChecked}" Value="True">
<Setter TargetName="txtbox1" Property="Foreground" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="lb_listcmmts" ItemsSource="{Binding Tables[0]}" ItemTemplate="{StaticResource Listboxcmmt}">
<ListBox.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
</Style>
</ListBox.Resources>
</ListBox>
<ToggleButton x:Name="btn" Grid.Column="1" Content="Change Color" Width="100" Height="50" Margin="30" VerticalAlignment="Top"/>
</Grid>
</Window>
When ToggleButton unchecked.
Foreground="#072D55"
When ToggleButton checked.
Foreground="Red"
Instead of hardcoding the colour in the template, you could set the Foreground using the DynamicResource markup extension and just add another resource that defines the colour:
<Window.Resources>
<SolidColorBrush x:Key="foreground" Color="#072D55" />
<DataTemplate x:Key="Listboxcmmt">
<Border>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="txtbox1" Text="{Binding U_Name}"
Foreground="{DynamicResource foreground}"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
Then it's simply a matter of replacing the resource:
private void Button_Click(object sender, RoutedEventArgs e)
{
Resources["foreground"] = Brushes.White;
}

how to resize this wpf button

I am not good at WPF and I am struggling with this a bit. I have a WPF window that has the following code:
<ContentControl.Content>
<Button Name="btnUpdateCommand" HorizontalAlignment="Right" Grid.Row="2" Command="{Binding UpdateCommand}" Height="23" Margin="0,4">
<StackPanel Orientation="Horizontal" Name="txtUpdate" HorizontalAlignment="Right">
<TextBlock Text="{Binding InstallButtonText}" DockPanel.Dock="Right" Margin="5,2,0,0" HorizontalAlignment="Right"></TextBlock>
<TextBlock Text="{Binding FormCloseCountDown}" DockPanel.Dock="Right" Margin="5,2,0,0"></TextBlock>
</StackPanel>
</Button>
</ContentControl.Content>
How do a resize btnUpdateCommand when I have localization text. I tried changing the alignment of the TextBlock etc. but no joy.
As an example this is what the button look like when it has english
And this is what the button looks like when it has french
What am I missing?
Here is the entrie XAML:
<UserControl x:Class="UpdateCheckModule.UpdateCheckProgress"
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"
d:DesignHeight="300" d:DesignWidth="300"
Height="250" Width="500">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="175"></RowDefinition>
<RowDefinition Height="10"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0">
<ContentControl.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="95"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="23"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" Grid.Row="0" FontSize="18" />
<TextBlock Text="{Binding Status}" Grid.Row="1" />
<Border Grid.Row="2" BorderThickness="1" BorderBrush="DarkGray">
<ProgressBar Value="{Binding ProgressPercentage}" Foreground="#FF10AAE7"></ProgressBar>
</Border>
</Grid>
</ContentControl.Content>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Visibility" Value="Visible"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HideProgress}" Value="True">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<ContentControl Grid.Row="0">
<ContentControl.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="115"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" Grid.Row="0" FontSize="18" />
<Image Source="pack://application:,,,/UpdateCheckModule;component/sedv2.ico" Grid.Column="1"></Image>
<TextBlock Text="{Binding ReleaseNotesText}" Grid.Row="1" Grid.ColumnSpan="2"/>
<Border BorderThickness="1" BorderBrush="DarkGray" Grid.Row="2" Grid.ColumnSpan="2">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock Text="{Binding DeploymentManifest.ReleaseNotes}" Background="White" Margin="5"></TextBlock>
</ScrollViewer>
</Border>
</Grid>
</ContentControl.Content>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HideProgress}" Value="True">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<Button Name="btnSkip" HorizontalAlignment="Left" Grid.Row="2" Content="{Binding SkipButtonText}" Width="100" Command="{Binding SkipCommand}" Height="23">
</Button>
<ContentControl Grid.Row="2">
<ContentControl.Content>
<Button Name="btnUacRestartCommand" HorizontalAlignment="Right" Grid.Row="2" Width="175" Command="{Binding UacRestartCommand}" Height="23">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Shield}" DockPanel.Dock="Left"></Image>
<TextBlock Text="{Binding AdminInstallButtonText}" DockPanel.Dock="Right" Margin="5,2,0,0"></TextBlock>
<TextBlock Text="{Binding FormCloseCountDown}" DockPanel.Dock="Right" Margin="5,2,0,0"></TextBlock>
</StackPanel>
</Button>
</ContentControl.Content>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Visibility" Value="Collapsed"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RequireUAC}" Value="True">
<Setter Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
<ContentControl Grid.Row="2">
<ContentControl.Content>
<Button Name="btnUpdateCommand" HorizontalAlignment="Right" Grid.Row="2" Width="175" Command="{Binding UpdateCommand}" Height="23">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding InstallButtonText}" DockPanel.Dock="Right" Margin="5,2,0,0"></TextBlock>
<TextBlock Text="{Binding FormCloseCountDown}" DockPanel.Dock="Right" Margin="5,2,0,0"></TextBlock>
</StackPanel>
</Button>
</ContentControl.Content>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Visibility" Value="Visible"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RequireUAC}" Value="True">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Grid>
You're explicitly setting the Width of the Button (to 175). Remove this attribute; this will allow the Button to determine its own optimal width.
While you're at it, remove the DockPanel.Dock attributes on the TextBlocks; these attributes do nothing since the TextBlocks are inside a StackPanel, not a DockPanel.

WPF Change style using blend

Is it possible using only xaml to change for example Property in style by blend triggers? For example after firing event Checked on first RadioButton change property Visibility in style FirstStyle on Visible.
<Window x:Class="switch_style.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Interactions="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="FirstStyle" TargetType="Label" x:Name="block">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</Window.Resources>
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Label Style="{DynamicResource FirstStyle}">First</Label>
<Label>Second</Label>
<Label>Third</Label>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Vertical">
<RadioButton Width="60" HorizontalAlignment="Left" Content="First">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Checked">
<Interactions:ChangePropertyAction TargetName="{Binding block}" PropertyName="Visibility" Value="Visible"/>
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</RadioButton>
<RadioButton Width="60" HorizontalAlignment="Left">Second</RadioButton>
<RadioButton Width="60" HorizontalAlignment="Left">Third</RadioButton>
</StackPanel>
</Grid>
</Grid>
</Window>
A Style object becomes immutable the moment it is applied to a Control. If this Style is not applied yet, yes you can change it.
So, you should create 2 separate Styles and choose a Style based on Trigger.
Since, I am not too sure why you want to do only in XAML, but here is my attempt and it works.
I updated your style to the following:
<Style x:Key="FirstStyle" TargetType="Label">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
And then, I set DataContext on Labels to the corresponding RadioButtons. Here is the full XAML:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style x:Key="FirstStyle" TargetType="Label">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Label Content="First" DataContext="{Binding ElementName=radioButton1}" Style="{DynamicResource FirstStyle}"/>
<Label Content="Second" DataContext="{Binding ElementName=radioButton2}" Style="{DynamicResource FirstStyle}"/>
<Label Content="Third" DataContext="{Binding ElementName=radioButton3}" Style="{DynamicResource FirstStyle}"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Vertical">
<RadioButton
x:Name="radioButton1"
Width="60"
HorizontalAlignment="Left"
Content="First"/>
<RadioButton
x:Name="radioButton2"
Width="60"
HorizontalAlignment="Left"
Content="Second"/>
<RadioButton
x:Name="radioButton3"
Width="60"
HorizontalAlignment="Left"
Content="Third"/>
</StackPanel>
</Grid>
</Grid>
</Page>
It would have probably been easier if we could bind RadioButton's IsChecked and Labels Visibility to the same property on a backing ViewModel.
Another approach to this problem would be #AnjumSKhan's answer.

Create a WPF Custom ComboBox

What I'm trying to do is a combobox that have the favorite values on top, with a different background color and button. Right now I have:
<UserControl x:Class="ComboBoxWithButton"
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"
Name="root"
d:DesignWidth="300" Height="25">
<ComboBox
x:Name="ComboBoxBtn"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="0,0,0,-1"
Width="300"
ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedItem="{Binding Path=Selected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}">
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
????
</Style>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="#FFE6E6FA"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding CommandButton, ElementName=root}"
CommandParameter="{Binding}">+</Button>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</UserControl>
Right now I have an Add button so I can add my items as favorites. But what I want now is, based on the item I represent it as favorite or not.
Case is a favorite have a different background color an a [-] button (to remove). Case is not the background is white as usual and have a [+].
See if a ContentControl helps you here in place of where you are using a Button.
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ...}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="#FFE6E6FA"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding CommandButton, ElementName=root}"
CommandParameter="{Binding}">+</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ...}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="Background" Value="Yellow"/>
</Style>
</Grid.Style>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Width="250" />
<Button Grid.Column="1" Command="{Binding CommandButton, ElementName=root}"
CommandParameter="{Binding}">-</Button>
</Grid>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>

WPF data binding to a parent property inside HierarchicalDataTemplate

I have the following data template in my listbox:
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="#FF575757" BorderThickness="0,0,0,1">
<Grid HorizontalAlignment="Stretch" Tag="{Binding}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" SharedSizeGroup="Name"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="DeviceIcon" DataContext="{Binding Path=device}" Source="{Binding Path=StatusIcon}" Width="64" Height="64" Grid.Column="0" Grid.RowSpan="2" RenderOptions.BitmapScalingMode="HighQuality" Margin="3"></Image>
<StackPanel Grid.Column="1" >
<TextBlock x:Name="DeviceName" DataContext="{Binding Path=device}" Text="{Binding Path=DeviceName}" FontWeight="Bold" Foreground="#FF00008F" FontSize="14.667"/>
<TextBlock x:Name="PluginName" Text="{Binding Path=PluginName}" />
</StackPanel>
<Menu x:Name="MainMenu" VerticalAlignment="Top" Padding="0,3" Grid.Column="1" Grid.Row="1" ItemsSource="{Binding deviceMenu}">
<Menu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Items}">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<Image Source="{Binding Icon}" Width="16" Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Icon}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock Text="{Binding Text}"/>
</StackPanel>
</HierarchicalDataTemplate>
</Menu.ItemTemplate>
<Menu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding ClickCommand}" />
<Setter Property="CommandParameter" Value="{Binding device}" />
</Style>
</Menu.ItemContainerStyle>
</Menu>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
The MenuItem's are bound to a property named deviceMenu in the root object. But the root object also contains a property called device which needs to be mapped to the CommandParameter property.
So how do I reach up and out of deviceMenu back to the parent object to access its properties?
Blame it on fatigue... The answer was pretty simple:
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.device}" />

Categories

Resources