Custom style tooltip and binding to button WPF with code xaml? - wpf

I would like to create a style for the tooltip and use it always binding to each button.
I can only do so from XAML?
I have done this for now:
<Window.Resources>
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Grid Width="200" Height="Auto" MinHeight="80">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" FontWeight="Bold"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{Binding Path=TitleTT}"/>
<Image Grid.Column="0" Grid.RowSpan="2" Source="{Binding Path=ImageTT}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" Margin="2"
HorizontalAlignment="Left" VerticalAlignment="Center"
Text="{Binding Path=DescriptionTT}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Now, I want to build a button in another user control.
What should I do?
What's wrong? why can not join anything?
Thanks for the help.
Code Button:
<Button Name="button_conf" Content="{DynamicResource Button_Confirm}" Margin="18,10"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Click="button_conf_Click">
<Button.ToolTip>
<ToolTip Style=ToolTip TitleTT="{DynamicResource ToolTip_title__confirm_defsce}"
ImageTT="/Images/xsd.jpg" DescriptionTT="The button confirm....:"/>
</Button.ToolTip>
</Button>

I can see at least the following two typos:
1.
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}"
should be
<Style x:Key="ToolTipStyle" TargetType="{x:Type ToolTip}"
Of course, you can use another name than ToolTipStyle.
2.
<ToolTip Style=ToolTip
should be
<ToolTip Style="{StaticResource ToolTipStyle}"
Apart from that, the properties TitleTT, ImageTT and DescriptionTT do not exist on the ToolTip control.

Related

Get Header name

Hello I am a bit lost with the control Templates, I have an expander and some control-styles that apply onto the Expander.
So the idea is to let the User insert the header
<Expander Name="MyExpanderExpander" Style="{StaticResource MyExpanderNewGeneration}" Header="UserChoice" OverridesDefaultStyle="True" VerticalAlignment="Top" Margin="0,0,0,0" Height="210">
So now the Style : MyExpanderNewGeneration should get the header Name : UserChoic
The ToggleButton has to get the Header Name : UserChoice and here is my problem ..but how to do it?
my Style applying is
<Style TargetType="Expander" x:Key="MyExpanderNewGeneration" BasedOn="{StaticResource BaseControlStyle}" >
<!--x:Key="GroupBoxStyle"-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<!--Grid Rows split the GroupBox into two areas -->
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Header area-->
<Border Name="HeaderArea"
Grid.Row="0"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="1"
CornerRadius="2,2,0,0" >
<ToggleButton x:Name="ExpanderButton"
Grid.Row="0"
Grid.Column="0"
Margin="0,0,0,0"
VerticalAlignment="Top"
Template="{StaticResource TestToggleButton}"
Content="{TemplateBinding Header}"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True">
</ToggleButton>
Herer I want to get the UserChoice Name.
<ControlTemplate x:Key="TestToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Foreground="White" Width="300" Grid.Column="0" FontSize="15"
HorizontalAlignment="Left" FontWeight="Normal" Something={HEADER???}
How to solve this?
Since you are setting Content="{TemplateBinding Header}" in your ExpanderButton, you will need to bind to the Content property inside your TestToggleButton style's control template:
<ControlTemplate x:Key="TestToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label
...
Content={TemplateBinding Content} />
...
</Grid>
</ControlTemplate>

The width of StackPanel inside the button is very narrow.(WPF)

I want to make a button with an image similar to the following:
For which I have written the following in xaml:
<Button
Style="{DynamicResource BotonRedondo2}"
Width ="AUTO"
Cursor="Hand"
Background="#3b5998"
Grid.Column="0">
<StackPanel Width ="Auto" Orientation="Horizontal" >
<Image HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
<StackPanel>
</Button>
But the result is as follows:
The width of the StackPanel does not match the width of the button.
Any suggestions on how to solve the problem?
Comments or questions are welcome
UPDATE
Maybe I should indicate that the button is in a column of a grid as follows:
<Grid
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button
Style="{DynamicResource BotonRedondo2}"
Width ="AUTO"
Cursor="Hand"
Background="#3b5998"
Grid.Column="0">
<StackPanel Width ="Auto" Orientation="Horizontal" >
<Image HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
</StackPanel>
</Button>
<Button
Style="{DynamicResource BotonRedondo2}"
Grid.Column="1"
Width ="Auto"
Background="Orange"
Content="LOGIN2"
Margin="3"/>
</Grid>
If I remove "Auto", the button looks like this:
UPDATE
The style that applies to the button is as follows:
<Style TargetType="Button" x:Key="BotonRedondo2">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="0"
Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
StackPanel in Horizontal orientation stacks items next to each other. It basically doesn't care about the HorizontalAlignment of items inside it.
You can use a Grid instead:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" Source="/Test;component/Imagenes/face.png"/>
<TextBlock Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Text="LOGIN WITH XXXXX" />
</Grid>
The above will give you the desired look.
You need to remove Width="Auto" from the Button and to set Button's property HorizontalContentAlignment="Stretch".
Also, consider using DockPanel or Grid instead of StackPanel:
<Button HorizontalContentAlignment="Stretch">
<DockPanel>
<Image Source="/Test;component/Imagenes/face.png"/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="LOGIN WITH XXXXX" />
</DockPanel>
</Button>
In the style of the button it should be written like this:
CornerRadius="4">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Center"/>

WPF: How to ignore defined style for concrete control

I have the Rectangle control style (for the type of Rectangle) defined in resource dictionary and it reflects the style for a Menu control also.
How to ignore these settings for Menu and leave it for (just) Rectangle? - Drawing purposes in canvas .... The Rectangle control is added to canvas dynamically from code behind. In main window is dockpanel, grid, menu, textblock and canvas controls. Style for rectangle also harm style properties for Menu (needed to keep the default style).
Thanks for advice
Main window controls:
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True">
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Menu Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Height="21" Name="menu" Style="{StaticResource ResourceKey=menuStyle}">
<MenuItem Header="File">
<MenuItem Header="Open image" Command="{Binding DoCommand}" CommandParameter="OpenImage"/>
<MenuItem Header="Exit" Command="{Binding DoCommand}" CommandParameter="Exit"/>
</MenuItem>
</Menu>
<RadioButton Margin="5" Grid.Row="1" Grid.Column="0" Content="Text selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Text}" />
<RadioButton Margin="5" Grid.Row="1" Grid.Column="1" Content="Picture selection" GroupName="ObjectType" IsChecked="{Binding Path=ObjectType, Mode=TwoWay, Converter={StaticResource ResourceKey=RadioButtonTypeConverter}, ConverterParameter=Picture}" />
</Grid>
<pt:PropertyControl DockPanel.Dock="Right" SelectedObject="{Binding SelectedObject}" MinWidth="150"/>
<TextBlock DockPanel.Dock="Bottom" Height="100" Margin="5" Background="#FFF9F9F9">
</TextBlock>
<Canvas Name="canvas" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" Background="White" Width="{Binding ElementName=ImgEdit, Path=Width}" Height="{Binding ElementName=ImgEdit, Path=Height}" MinWidth="300" MinHeight="100" VerticalAlignment="Top" MouseMove="canvas_MouseMove" MouseLeftButtonUp="canvas_MouseLeftButtonUp" >
<Image x:Name="ImgEdit" Source="{Binding BackgroundImage}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
</DockPanel>
Code of my Style resource dictionary:
<Style TargetType="{x:Type Rectangle}" >
<Setter Property="Fill" Value="Yellow" />
<Setter Property="Opacity" Value="0.2"/>
<Setter Property="StrokeThickness" Value="2"/>
<Setter Property="Stroke" Value="Red" />
</Style>

16x16 pixel images in RibbonApplicationMenuItem gets stretched

I am having a ribbon application menu that looks like this:
<ribbon:RibbonWindow>
<DockPanel>
<ribbon:Ribbon DockPanel.Dock="Top">
<ribbon:Ribbon.ApplicationMenu>
<ribbon:RibbonApplicationMenu>
<ribbon:RibbonApplicationMenuItem Header="Users"
ImageSource="Users16x16.png"
Command="{Binding FooBinding}"/>
</ribbon:RibbonApplicationMenu>
</ribbon:Ribbon.ApplicationMenu>
</ribbon:Ribbon>
</DockPanel>
</ribbon:RibbonWindow>
The resulting image looks like this, stretched.
So how do I have a ribbon application menu item with a height that adapts to the image size instead of stretching?
Change the control template like:
<ribbon:RibbonApplicationMenuItem Command="{Binding FooBinding}">
<ribbon:RibbonApplicationMenuItem.Template>
<ControlTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="Users16x16.png"/>
<TextBlock Grid.Column="1">Users</TextBlock>
</Grid>
</ControlTemplate>
</ribbon:RibbonApplicationMenuItem.Template>
</ribbon:RibbonApplicationMenuItem>
If you want to use control template as Style in your dictionary:
<Style x:Key="16x16ImageStyle" TargetType="{x:Type ribbon:RibbonApplicationMenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ribbon:RibbonApplicationMenuItem}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="None"
Grid.Column="0" Source="{TemplateBinding ImageSource}"/>
<TextBlock Grid.Column="1" Text="{TemplateBinding Header}"></TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and recall it in your ribbon:
<ribbon:RibbonApplicationMenuItem Header="Users"
ImageSource="Users16x16.png"
Command="{Binding FooBinding}"
Style="{StaticResource 16x16ImageStyle}"/>

Using HierarcicalDataTemplates in conjunction with TreeViewItem control templates

I am having some difficulty figuring out how to template the following TreeView item layout:
I have several items, SearchList, which contains a collection of Search, which contains a collection of DataSet (sort of, but that is beside the point). What I am having difficulty with is styling each node level the way I want. I am using MVVM, and the TreeViews ItemsSource property is set to an ObservableCollection of SearchListViewModels which in turn contain my objects all the way down the object tree.
I can successfully style the SearchList HierarchicalDataTemplate to display them correctly. Where I get hung up is on SearchTerm nodes styling. I want the DataSets to be represented in a wrap panel or uniform grid (I haven't decided yet) to the right of the SearchTerm content area. I have modified a TreeViewItem control template to behave this way I think), however if I set it in the ItemContainerStyle property of the Search HierarchicalDataTemplate, it does nothing. All that gets displayed is the content for the Search.
My Altered TreeViewItem Template
<Style TargetType="{x:Type TreeViewItem}" x:Key="AlteredTreeViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MinWidth="19" />
<ColumnDefinition Width="0.414*" />
<ColumnDefinition Width="0.586*"/>
</Grid.ColumnDefinitions>
<Border x:Name="Bd" HorizontalAlignment="Stretch"
Grid.Column="1" Grid.ColumnSpan="1" Background="#7F058956">
<ContentPresenter x:Name="PART_Header" Margin="10,0" />
</Border>
<WrapPanel x:Name="ItemsHost"
Grid.Column="2" IsItemsHost="True"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My Search Hierarchical Data Template
<HierarchicalDataTemplate DataType="{x:Type local:SearchViewModel}" ItemsSource="{Binding MySearch.Custodians}" ItemContainerStyle="{StaticResource AlteredTreeViewItem}">
<TextBlock Text="{Binding MySearch.SearchName}" Foreground="Black" FontFamily="Arial" FontSize="16"/>
</HierarchicalDataTemplate>
Surely it is possible to both style differently and have child items laid out differently? How can this be achieved?
It seems that you are pretty close to what you're after. I tried to recreate your scenario based on the code you posted and I noted some problems with it (which of course are based on my interpretation of the code you posted)
You are missing the ContentSource="Header" part of the ContentPresenter
I think you are applying the ItemContainerStyle at the wrong HierarchicalDataTemplate level. It should be specified on the parent in order to affect the children (in your case SearchListViewModel).
The default Template for TreeViewItem lays out the ContentPresenter in an Auto sized ColumnDefinition so the WrapPanel won't succesfully wrap unless you modify the ItemContainerStyle for the parent as well. I changed it to a UniformGrid in my sample below
With the changes from above and a few other things I got a result that looks like this which hopefully is pretty close to what you're after
I uploaded the sample solution here: https://www.dropbox.com/s/4v2t8imikkagueb/TreeViewAltered.zip?dl=0
And here is the Xaml code for it (too much code to post it all..)
<Window.Resources>
<!-- DataSet-->
<HierarchicalDataTemplate DataType="{x:Type data:DataSet}">
<Border BorderThickness="3"
BorderBrush="Gray"
Background="Green">
<TextBlock Text="{Binding Path=Tables[0].TableName}"
Margin="5"/>
</Border>
</HierarchicalDataTemplate>
<!-- SearchViewModel -->
<HierarchicalDataTemplate DataType="{x:Type viewModel:SearchViewModel}"
ItemsSource="{Binding DataSets}">
<TextBlock Text="{Binding DisplayName}"
Foreground="Black"
FontFamily="Arial"
FontSize="16"/>
</HierarchicalDataTemplate>
<!-- SearchListViewModel -->
<HierarchicalDataTemplate DataType="{x:Type viewModel:SearchListViewModel}"
ItemsSource="{Binding SearchList}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="19" />
<ColumnDefinition Width="0.414*" />
<ColumnDefinition Width="0.586*"/>
</Grid.ColumnDefinitions>
<Border x:Name="Bd"
HorizontalAlignment="Stretch"
Grid.Column="1"
Grid.ColumnSpan="1"
Background="#7F058956">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<UniformGrid x:Name="ItemsHost"
Grid.Column="2"
Columns="3"
IsItemsHost="True"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<TextBlock Text="{Binding DisplayName}"
FontSize="20"/>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView ItemsSource="{Binding SearchListViewModels}" />
</Grid>
Something I learnt a long time ago when trying to create a similar interface was that you are better using a ListBox than a TreeView.
Why?
If you only have one level of expansion (as it appears from your sample) you will a lot more control of the layout as you have a single DataTemplate to style.
It is lot easier to customize a ListBox than a TreeView as you do not have be concerned with the GridViewColumnHeader and GridViewColumnPresenters etc.
To get the expansion part (which is why you initially selected a TreeView), simply use a Grid with two rows defined and an Expander in the second row bound to the IsChecked property of a ToggleButton. See the example that I pulled from my Log Viewer.
<DataTemplate>
<Grid Margin="0,0,0,3" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" SharedSizeGroup="SSG_TimeIcon"/>
<ColumnDefinition Width="120" SharedSizeGroup="SSG_Time"/>
<ColumnDefinition Width="30" SharedSizeGroup="SSG_LevelIcon"/>
<ColumnDefinition Width="70" SharedSizeGroup="SSG_Level"/>
<ColumnDefinition Width="*" SharedSizeGroup="SSG_Message"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- ProgramTime -->
<Rectangle Grid.Column="0" Grid.Row="0" Margin="0,0,0,0" Width="16" Height="16" VerticalAlignme="Top" HorizoalAlignme="Stretch" Fill="{StaticResource Icon_Timer}"/>
<TextBlock Grid.Column="1" Grid.Row="0" Margin="5,0,0,0" VerticalAlignme="Top" HorizoalAlignme="Stretch" Text="{Binding Path=TimeStamp, Converter={StaticResource ObjectToStringConverter}}" ToolTip="{Binding Path=ProgramTime}"/>
<!-- Level -->
<Rectangle Grid.Column="2" Grid.Row="0" Margin="10,0,0,0" Width="16" Height="16" VerticalAlignme="Top" HorizoalAlignme="Stretch" Fill="{Binding Path=Level, Converter={StaticResource MappingConverterNinjaLogLevelEnumToBrushResource}}"/>
<TextBlock Grid.Column="3" Grid.Row="0" Margin="5,0,0,0" Text="{Binding Path=LevelFriendlyName}" VerticalAlignme="Top" HorizoalAlignme="Stretch"/>
<!-- Message -->
<StackPanel Grid.Column="4" Grid.Row="0" Margin="10,0,0,0" Orieation="Horizoal" >
<TextBlock Margin="0,0,0,0" Text="{Binding Path=LogMessage}" TextWrapping="Wrap" VerticalAlignme="Top" HorizoalAlignme="Stretch"/>
<ToggleButton x:Name="ExpandExceptiooggleButton" VerticalAlignme="Top" Margin="5,0,0,0" IsChecked="False"
Coe="Show Details" Tag="Hide Details" Style="{StaticResource TextButtonStyle}"
Foreground="{StaticResource BlueBrush}" Background="{StaticResource RedBrush}"
Visibility="{Binding Path=HasException, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
<Expander IsExpanded="{Binding Path=IsChecked, ElemeName=ExpandExceptiooggleButton}" Style="{StaticResource CoeExpanderStyle}"
Margin="10,0,0,0" Grid.Column="4" Grid.Row="1">
<Border BorderBrush="{StaticResource DarkGreyBrush}" BorderThickness="1,0,0,0">
<TextBlock Text="{Binding Path=Exception}" Margin="5,0,0,0"/>
</Border>
</Expander>
</Grid>
</DataTemplate>
Can you see how much easier it is to define a header and expandable body. If you do have a need for nested data, add a Level property your view model (you are using MVVM aren't you?!) and then create a IValueConverter that returns a Margin (i.e. Thickness) to fake the indent.

Resources