TreeView with buttons - wpf

I have a TreeView where each node has an icon and a descriptive text. But I do not want any node can be selected. Instead, I want that each node act as a button. It run a command when the user press it. But it may not look like a button or hyperlink
This is what I tried so far. The problem is that the text is blue and the text underlined. In addition, sometime the node is selected and therefore blue.
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type vm:ListGroupViewModel}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Text}" FontWeight="Bold" ></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type vm:ListNodeViewModel}">
<TextBlock>
<Hyperlink TextDecorations="{x:Null}" Command="{Binding ClickCommand, Mode=OneTime}">
<StackPanel Orientation="Horizontal">
<Image Margin="0,2,2,0" Source="{Binding Icon}" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</Hyperlink>
</TextBlock>
</DataTemplate>
</TreeView.Resources>

You should override hyperlink style:
<Style x:Key="HyperlinkStyle" TargetType="Hyperlink">
<Setter Property="Foreground"
Value="Black"/>
<Setter Property="TextDecorations"
Value="{x:Null}"/>
</Style>
<DataTemplate DataType="{x:Type vm:ListNodeViewModel}">
<TextBlock>
<Hyperlink Command="{Binding ClickCommand, Mode=OneTime}"
Style="{StaticResource HyperlinkStyle}">
<StackPanel Orientation="Horizontal">
<Image Margin="0,2,2,0" Source="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</Hyperlink>
</TextBlock>
</DataTemplate>
To hide tree item selection you could override SystemColors.HighlightBrushKey, which tree view uses to highlight items:
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>

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>
...

WPF: show all my object properties over my Combobox tooltip

So i have ComboBox binding with my Person object list and i want to show all my object properties over my Combobox ToolTip.
Currently this is what i try:
<ComboBox
materialDesign:HintAssist.Hint="Network inteface"
materialDesign:HintAssist.IsFloating="True"
ItemsSource="{Binding Persons}"
Style="{StaticResource MaterialDesignFloatingHintComboBox}">
<ComboBox.ToolTip>
<ToolTip>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Id}"/>
</StackPanel>
</ToolTip>
</ComboBox.ToolTip>
</ComboBox>
And all i can see this is empty little line of ToolTip
As I understand your issue. You have some confusion. You want to show all information in tooltip of invidual item i.e. comboboxItem, instead of comboBox. In your posted code, you are trying to get information in tooltip of combobox.
For combobox item, Please go through following code
<ComboBox ItemsSource="{Binding Persons}" SelectedValuePath="Id">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}">
<TextBlock.ToolTip>
<ToolTip>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Id}"/>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Description}"/>
</StackPanel>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
and here is result for reference

Change displayed text in XAML Combobox multi selection

I have the following code to allow users to select multiple items from a combobox. However when they click one item, it makes this the displayed text when combobox closes. Can I change the displayed text to something that isnt just the item selected. For example if the users select items A,B and D, I want the text part of the combobox to show "A, B, D"
<ComboBox ItemsSource="{Binding ListOfItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="20" />
<TextBlock Text="{Binding DisplayName}" Width="110" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Thanks
You could use a ContentControl with a Style that changes the ContentTemplate property for the selected item. The following sample markup should give you the idea.
<ComboBox ItemsSource="{Binding ListOfItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- the template for the items in the dropdown list -->
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Width="20" />
<TextBlock Text="{Binding DisplayName}" Width="110" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- the template for the selected item-->
<DataTemplate>
<ItemsControl ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=ComboBox}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" Margin="0 0 5 0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Please refer to the following similar question for more information.
Can I use a different Template for the selected item in a WPF ComboBox than for the items in the dropdown part?

davidpoll's printcollection

I'm trying to use David Poll's printcollection control, from the SLaB project- www.davidpoll.com but for some reason no items get shown. Maybe it's something with my itemtemplate, please have a look at this:
<Style x:Key="PrintStyle"
TargetType="SLaB:CollectionPrinter">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<sdk:Label x:Name="lblTitle" HorizontalAlignment="Left" Margin="0,8,0,0" VerticalAlignment="Top" Content="{Binding Source={StaticResource ResourceWrapper}, Path=NoteEditorResources.Title}"/>
<sdk:Label x:Name="lblTitleResult" HorizontalAlignment="Left" Margin="42,8,0,0" VerticalAlignment="Top" Content="{Binding Path=Title}"/>
<sdk:Label x:Name="lblDateCreated" HorizontalAlignment="Right" Margin="0,8,156,0" VerticalAlignment="Top" Content="{Binding Source={StaticResource ResourceWrapper}, Path=NoteEditorResources.DateCreated}"/>
<sdk:Label x:Name="lblDateCreatedResult" HorizontalAlignment="Right" Margin="0,8,113,0" VerticalAlignment="Top" Content="{Binding Path=DateCreated}"/>
<RichTextBox x:Name="rtbContent" Margin="0,28,0,8" Width="582" Xaml="{Binding Content}" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Right"
Orientation="Horizontal">
<TextBlock Text="{Binding CurrentPage, StringFormat='{}Page {0} '}" />
<TextBlock Text="{Binding PageCount, StringFormat='{}/ {0}'}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="FooterTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel HorizontalAlignment="Center"
Orientation="Horizontal">
<TextBlock Text="{Binding FirstItemValue.Name}" />
<TextBlock Text=" - " />
<TextBlock Text="{Binding LastItemValue.Name}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I've used his printing control, but I never modified the itemtemplate. I used his TestPrinter.xaml as a template and filled in the HeaderTemplate, FooterTemplate, and the BodyTemplate with my code.
The BodyTemplate being the important one to take a look at. Here is the BodyTemplate section from his example:
<Printing:CollectionPrinter.BodyTemplate>
<DataTemplate>
<sdk:DataGrid ItemsSource="{Binding CurrentItems}"
AutoGenerateColumns="False"
VerticalScrollBarVisibility="Disabled">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Name}"
Header="Name" />
<sdk:DataGridTextColumn Binding="{Binding Address}"
Header="Address" />
<sdk:DataGridTextColumn Binding="{Binding Age}"
Header="Age" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</DataTemplate>
</Printing:CollectionPrinter.BodyTemplate>
The important thing is to set the CurrentItems as the source for your control that will be used to display your collection. This way it can automatically calculate how many items to display in the page before they cut off.

WPF : InputBindings on a StackPanel

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.

Resources