WPF : InputBindings on a StackPanel - wpf

I want to put a command on a ListBoxItem. The ListBoxItem use a DataTemplate composed of a StackPanel (containing an Image and a TextBlock, both using Binding). I want that the doubleclick on that ListBoxItem fire the command.
I have tried this :
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False">
</StackPanel>
</DataTemplate>
I have also tried to put the Command Resources on a StackPanel containing this StackPanel, without any change.
I am certain of my binding because when I put the InputBindings part on the TextBlock, it works.
Thanks

Try handling the event in the ListBox instead of the StackPanel:
<ListBox>
<ListBox.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</ListBox.Resources>
<ListBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</ListBox.InputBindings>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox>

My code finally looks like this :
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
Thanks anyway, Mr Poulin.

Related

How to stretch the content of a templated MenuItem using WPF

in my WPF application I have a Menu defined as follows:
<Menu
Grid.Column="1"
MinWidth="50"
MinHeight="50"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
Visibility="{Binding Path=ShowSynergies, Converter={StaticResource BoolToVisConverter}}">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
BorderBrush="Black"
BorderThickness="1"
ItemsSource="{Binding Path=CurrentlyAvailableSynergies, Source={StaticResource ResourceKey=VM}}">
<MenuItem.Header>
<TextBlock
Margin="5"
FontSize="18"
Text="{Binding Path=ActiveSynergy.Synergy, Source={StaticResource ResourceKey=VM}}"
TextAlignment="Center" />
</MenuItem.Header>
<MenuItem.ToolTip>
<TextBlock Text="{Binding Path=ActiveSynergy.Synergy, Source={StaticResource ResourceKey=VM}}" />
</MenuItem.ToolTip>
<MenuItem.Resources>
<HierarchicalDataTemplate DataType="{x:Type ent:VisualSynergy}" ItemsSource="{Binding Path=AvailableDiameters}">
<TextBlock Text="{Binding SynergyText}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type ent:VisualDiameter}">
<TextBlock
VerticalAlignment="Stretch"
Background="Purple"
Text="{Binding Path=VisualValue}">
<intr:Interaction.Triggers>
<intr:EventTrigger EventName="PreviewMouseLeftButtonDown">
<intr:InvokeCommandAction Command="{Binding Path=SelectSynergyCommand}">
<intr:InvokeCommandAction.CommandParameter>
<MultiBinding Converter="{StaticResource ResourceKey=StdMultiConverter}">
<Binding Path="." />
<Binding Path="." Source="{StaticResource ResourceKey=VM}" />
</MultiBinding>
</intr:InvokeCommandAction.CommandParameter>
</intr:InvokeCommandAction>
</intr:EventTrigger>
</intr:Interaction.Triggers>
</TextBlock>
</DataTemplate>
</MenuItem.Resources>
</MenuItem>
</Menu>
Everything is working as intended, all data is bound properly and updated when it should be updated.
My larges issue is that the final TextBlock (the one related to my VisualDiameter type) doe snot stretch to fill the whole MenuItem available space (see screenshot). I've tried also to redefine styles, but since I am inside the MenuItem resources definitions there is something missing and no stretching happens.
Looking ot other questions my issue seems related to the bizzarre definition of TreeView and MenuItem by Microsoft, but I am not confidend enough to start tinkering with basic templates.
You should define an ItemContainerStyle and bind the Command property of the MenuItem container rather than trying to stretch the TextBlock in the DataTemplate:
<MenuItem
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
BorderBrush="Black"
BorderThickness="1"
ItemsSource="{Binding Path=CurrentlyAvailableSynergies}">
<MenuItem.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding SelectSynergyCommand}" />
</Style>
</MenuItem.ItemContainerStyle>
<MenuItem.Header>
...

How to use converters without binding paths?

I have a Combobox whose ItemsSource is an ObservableCollection of int values.
My combobox itemtemplate consists on an image and a textblock which content is given by 2 converters.
How can I set this 2 bindings? The following code does not compile:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding, Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding, Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
You need to remove the , so:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>

Bind to other element in a stackpanel without name

I'm creating a DataTemplate in WPF, so it won't compile if I use x:Name. This is the relevant part of my code:
<DataTemplate>
<StackPanel>
<Image .../>
<Textbox Width={Binding to image?, Path=ActualWidth} />
</StackPanel>
</DataTemplate>
How can I bind to the Image without the use of name?
You can use RelativeSource:
<DataTemplate>
<StackPanel>
<Image Source="{Binding Photo}"/>
<TextBox Width="{Binding Path=Children[0].ActualWidth, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel, AncestorLevel=1}}" />
</StackPanel>
</DataTemplate>
You can't directly binding to Image but you can do that with StackPanel and property Children.

How add command to an ElementMenuItem?

I am trying to add a command to an ElementMenuItem, but the command can not be fired.
<Grid Name="MenuGrid">
<s:ElementMenu
Name="MainMenu"
ActivationMode="AlwaysActive"
ActivationHost="{Binding ElementName=MenuGrid}"
ItemsSource="{Binding Menu}">
<s:ElementMenu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Menu}" DataType="{x:Type s:ElementMenuItem}">
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<behaviours:EventToCommand Command="{Binding Source={StaticResource Locator}, Path=NavigatorMenu.SimpleCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Image Source="{Binding ImageUri}"></Image>
<TextBlock Text="{Binding Title}"
VerticalAlignment="Bottom"
HorizontalAlignment="Center">
</TextBlock>
</Grid>
</HierarchicalDataTemplate>
</s:ElementMenu.ItemTemplate>
</s:ElementMenu>
</Grid>
Does anyone know how to add a command to the menu? Thank you in advance.
No idea what those controls are but if they inherit from normal menus you should use the ItemContainerStyle to hook up commands:
<s:ElementMenu Name="MainMenu" ActivationMode="AlwaysActive"
ActivationHost="{Binding ElementName=MenuGrid}" ItemsSource="{Binding Menu}">
<s:ElementMenu.ItemContainerStyle>
<Style TargetType="s:ElementMenuItem">
<Setter Property="Command"
Value="{Binding Source={StaticResource Locator}, Path=NavigatorMenu.SimpleCommand}" />
</Style>
</s:ElementMenu.ItemContainerStyle>
<s:ElementMenu.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Menu}">
<Grid>
<Image Source="{Binding ImageUri}"/>
<TextBlock Text="{Binding Title}" VerticalAlignment="Bottom"
HorizontalAlignment="Center"/>
</Grid>
</HierarchicalDataTemplate>
</s:ElementMenu.ItemTemplate>
</s:ElementMenu>
This of course assumes that all the bindings actually work, if they don't you should probably debug them...
I don't know why but I find interaction triggers don't work in a Grid. Change your xaml to
<HierarchicalDataTemplate ItemsSource="{Binding Menu}" DataType="{x:Type s:ElementMenuItem}">
<ContentControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<behaviours:EventToCommand Command="{Binding Source={StaticResource Locator}, Path=NavigatorMenu.SimpleCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Image Source="{Binding ImageUri}"></Image>
<TextBlock Text="{Binding Title}"
VerticalAlignment="Bottom"
HorizontalAlignment="Center">
</TextBlock>
</Grid>
</ContentControl>
</HierarchicalDataTemplate>

Reusing a tooltip for several textboxes

What should I write in the value of the Text property of the tooltip resource so it would show the text of each textblock dynamically ?
<StackPanel x:Name="root">
<StackPanel.Resources>
<ResourceDictionary>
<ToolTip x:Key="tooltiptemplate">
<TextBlock Background="LightBlue" TextTrimming="WordEllipsis" Text="?????"/>
</ToolTip>
</ResourceDictionary>
</StackPanel.Resources>
<TextBlock Text="Mickel" ToolTip="{StaticResource tooltiptemplate}"/>
<TextBlock Text="Kim" ToolTip="{StaticResource tooltiptemplate}"/>
<TextBlock Text="Jenny" ToolTip="{StaticResource tooltiptemplate}"/>
</StackPanel>
{Binding PlacementTarget.Text, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}

Resources