Show Border on avalonEdit:TextEditor - c#

I am trying to get a border to show around an avalonEdit 'box' in a Wpf control but can't seem to make it happen.
I added BorderBrush="Black" BorderThickness="2" but clearly I am missing something.
I've googled but, despite my endeavors, I cannot find anything - I suspect I may not know the correct terminology to Google for because it feels like it should be straightforward!
Code as follows:
<Label Content="Account:" HorizontalAlignment="Left" Margin="10,28,0,0" VerticalAlignment="Top"/>
<TextBox Name ="textBoxAccount" HorizontalAlignment="Left" Height="23" Margin="66,28,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120"/>
<Label Content="Query:" HorizontalAlignment="Left" Margin="10,59,0,0" VerticalAlignment="Top"/>
<Button x:Name="btnGo" Content="Go!" HorizontalAlignment="Left" Height="25" Margin="10,342,0,0" VerticalAlignment="Top" Width="146"/>
<avalonEdit:TextEditor
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
x:Name="textEditor"
FontFamily="Consolas"
SyntaxHighlighting="AWQL"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
WordWrap="True"
Visibility="Visible"
BorderBrush="Black" BorderThickness="2"
FontSize="10pt" Margin="12,89.96,10,0" Height="229" VerticalAlignment="Top"/>
</Grid>
which renders like this:
but the 'avalonEdit' box doesn't seem to render the border so looks invisible unless/until a user clicks inside it and starts typing.
I'd really like the border to look the same as the simple textbox at the top of the user control but right now I'd settle for anything visible!

I only worked once with avalon before so I cooked up a quick project which does what you want.
As a disclaimer, AvalonEdit seems to ruin any attempt to put a border around it like you said. So I set it up using a grid to put a border around it.
It will look something like this:
And the code will look like this:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="600" Height="500"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Account:" HorizontalAlignment="Left" Margin="20,20" VerticalAlignment="Top" Height="26" Width="56" />
<TextBox Grid.Column="1" Grid.Row="0" Name="textBoxAccount" HorizontalAlignment="Left" Height="26" Margin="20" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120" />
<Label Grid.Column="0" Grid.Row="1" Content="Query:" HorizontalAlignment="Left" Margin="20,0" VerticalAlignment="Top" Height="26" Width="45" />
<Border Grid.ColumnSpan="2"
Grid.Row="2"
Grid.Column="0" BorderBrush="Black" BorderThickness="1"
Margin="20"
Height="230">
<avalonEdit:TextEditor
x:Name="textEditor"
FontFamily="Consolas"
SyntaxHighlighting="AWQL"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
WordWrap="True"
Visibility="Visible"
FontSize="10pt" VerticalAlignment="Top" Height="226"/>
</Border>
<Button Grid.Column="0" Grid.Row="3" x:Name="btnGo" Content="Go!" HorizontalAlignment="Left" Height="25" Margin="20"
VerticalAlignment="Top" Width="146" />
</Grid>
This is not exactly what you want, but a grid will help with other issues as well in the long run

This is the avalonEdit:TextEditor style (TextEditor.xaml):
<Style TargetType="{x:Type AvalonEdit:TextEditor}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
<Setter Property="FlowDirection" Value="LeftToRight"/> <!-- AvalonEdit does not support RTL, so ensure we use LTR by default -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type AvalonEdit:TextEditor}">
<ScrollViewer
Focusable="False"
Name="PART_ScrollViewer"
CanContentScroll="True"
VerticalScrollBarVisibility="{TemplateBinding VerticalScrollBarVisibility}"
HorizontalScrollBarVisibility="{TemplateBinding HorizontalScrollBarVisibility}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextArea}"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Left"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
/>
<ControlTemplate.Triggers>
<Trigger Property="WordWrap"
Value="True">
<Setter TargetName="PART_ScrollViewer"
Property="HorizontalScrollBarVisibility"
Value="Disabled" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And this is an explanation about why ScrollViewer doesn't show borders: https://social.msdn.microsoft.com/Forums/vstudio/en-US/a2310302-167b-44e2-bc23-825ff1610701/scrollviewer-border
So, I think the best way is to wrap the TextEditor inside a Border as Guerudo says or modify the template in Avalon code TextEditor.xaml.

I didn't work with avalonEdit but I can suggest you an other way : you could wrap your TextEditor inside a <Border> </Border>.
It's probably not the best solution but it is one.

The AvalonEdit community nicely fixed this problem by changing the TextEditor style from the project:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type AvalonEdit:TextEditor}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer
Focusable="False"
Name="PART_ScrollViewer"
CanContentScroll="True"
VerticalScrollBarVisibility="{TemplateBinding VerticalScrollBarVisibility}"
HorizontalScrollBarVisibility="{TemplateBinding HorizontalScrollBarVisibility}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TextArea}"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Left"
Padding="{TemplateBinding Padding}"
/>
</Border>

Related

WinUI 3 ComboBox Header is On Top of Control

When I use the Header property, the header rests on over the ComboBox so that the ComboBox is hidden behind the header, making the ComboBox unusable.
<ComboBox x:Name="DataGridFilter" Header="Filter By" Grid.Row="0" Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
ItemsSource="{x:Bind ViewModel.FilterList, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
I found this, but there is no example of how the resource can be used to move the header to be above the ComboBox (you'd think it did that by default). I also checked the grid row that contains this ComboBox, and there should be plenty of height for both the header and ComboBox.
How can I relocate the header so that it is vertically higher or to the left of the ComboBox?
As #Junjie Zhu mentions in the comments, you might want to reinstall the latest WindowsAppSDK.
If you need to locate the Header, let's say to the left side, this is an example for it.
Note: The default style comes from the default generic.xaml file. (This answer shows you how to find the generic.xaml file.)
MainPage.xaml
<Page
x:Class="ComboBoxTests.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ComboBoxTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.Resources>
<Style
BasedOn="{StaticResource DefaultComboBoxStyle}"
TargetType="ComboBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid x:Name="LayoutRoot">
<Grid.Resources>
...
</Grid.Resources>
<Grid.RowDefinitions>
<!-- This is for the "Header". We won't need this. But we need to change each Grid.Column and Grid.Row of the controls to move the Header to the left.
<RowDefinition Height="Auto" />
-->
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="38" />
</Grid.ColumnDefinitions>
<!-- This ContentPresenter is for the Header. -->
<ContentPresenter
x:Name="HeaderContentPresenter"
Grid.Row="0"
Grid.Column="0"
Margin="{ThemeResource ComboBoxTopHeaderMargin}"
VerticalAlignment="Top"
x:DeferLoadStrategy="Lazy"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
FlowDirection="{TemplateBinding FlowDirection}"
FontWeight="{ThemeResource ComboBoxHeaderThemeFontWeight}"
Foreground="{ThemeResource ComboBoxHeaderForeground}"
LineHeight="20"
TextWrapping="Wrap"
Visibility="Collapsed" />
<Border
x:Name="HighlightBackground"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="-4"
Background="{ThemeResource ComboBoxBackgroundFocused}"
BorderBrush="{ThemeResource ComboBoxBackgroundBorderBrushFocused}"
BorderThickness="{StaticResource ComboBoxBackgroundBorderThicknessFocused}"
CornerRadius="{StaticResource ComboBoxHiglightBorderCornerRadius}"
Opacity="0" />
<Border
x:Name="Background"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
MinWidth="{ThemeResource ComboBoxThemeMinWidth}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Control.IsTemplateFocusTarget="True"
CornerRadius="{TemplateBinding CornerRadius}"
Translation="0,0,1" />
<Rectangle
x:Name="Pill"
Grid.Row="0"
Grid.Column="1"
Margin="1,0,0,0"
Opacity="0"
Style="{StaticResource ComboBoxItemPill}">
<Rectangle.RenderTransform>
<CompositeTransform
x:Name="PillTransform"
ScaleY="1" />
</Rectangle.RenderTransform>
</Rectangle>
<ContentPresenter
x:Name="ContentPresenter"
Grid.Row="0"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<TextBlock
x:Name="PlaceholderTextBlock"
Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource ComboBoxPlaceHolderForeground}}"
Text="{TemplateBinding PlaceholderText}" />
</ContentPresenter>
<TextBox
x:Name="EditableText"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="0,0,0,0"
Padding="{ThemeResource ComboBoxEditableTextPadding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
x:Load="False"
AutomationProperties.Name="{TemplateBinding AutomationProperties.Name}"
BorderBrush="Transparent"
CornerRadius="{TemplateBinding CornerRadius}"
Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource ComboBoxPlaceHolderForeground}}"
Header="{TemplateBinding Header}"
PlaceholderText="{TemplateBinding PlaceholderText}"
Style="{TemplateBinding TextBoxStyle}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="Collapsed" />
<Border
x:Name="DropDownOverlay"
Grid.Row="0"
Grid.Column="2"
Width="30"
Margin="4,4,4,4"
HorizontalAlignment="Right"
x:Load="False"
Background="Transparent"
CornerRadius="{StaticResource ComboBoxDropDownButtonBackgroundCornerRadius}"
Visibility="Collapsed" />
<controls:AnimatedIcon
x:Name="DropDownGlyph"
Grid.Row="0"
Grid.Column="2"
Width="12"
Height="12"
MinHeight="{ThemeResource ComboBoxMinHeight}"
Margin="0,0,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
controls:AnimatedIcon.State="Normal"
AutomationProperties.AccessibilityView="Raw"
Foreground="{ThemeResource ComboBoxDropDownGlyphForeground}"
IsHitTestVisible="False">
<animatedVisuals:AnimatedChevronDownSmallVisualSource xmlns:animatedVisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals" />
<controls:AnimatedIcon.FallbackIconSource>
<controls:FontIconSource
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
Foreground="{ThemeResource ComboBoxDropDownGlyphForeground}"
Glyph="" />
</controls:AnimatedIcon.FallbackIconSource>
</controls:AnimatedIcon>
<ContentPresenter
x:Name="DescriptionPresenter"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
x:Load="False"
Content="{TemplateBinding Description}"
Foreground="{ThemeResource SystemControlDescriptionTextForegroundBrush}" />
<Popup x:Name="Popup">
...
</Popup>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid
ColumnDefinitions="Auto,*"
RowDefinitions="Auto,*">
<ComboBox
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Header="Filter by"
ItemsSource="{x:Bind ViewModel.FilterList, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Page>

C# WPF - ControlTemplate specify properties of a child

I'm a newby in WPF, so please exuse if this is a trivial question...
I need to create many similar controls, each of them consists of a picture and a title below. I try this way:
XAML (Style with a template inside of a ResourceDictionary):
<Style x:Key="myStyle" TargetType="{x:Type Button}">
<Setter Property="Width" Value="300"></Setter>
<Setter Property="Height" Value="320"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Margin="5 2" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Background="White" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Width="300" Height="250" x:Name="picGraph" Source="picture1.png" />
<TextBlock Grid.Row="1" Text="title1" HorizontalAlignment="Center" />
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
XAML (Usage):
<Button Style="{StaticResource TestGenResultsGraph}"/>
That's all good, but I want to be able to change the Source-property of the image and Text-property of the textblock when I use the Button (to use more than only picture1.png).
I tried to add a setter for a Source-property, but it doesn't work this way, because Button-control doesn't have it:
<Setter Property="Source" Value="picture1.png"/> <!-- Error: The member "Source" is not recognized or is not accessible-->
So generally I would like to have a possibility of usage like that:
<Button Style="{StaticResource myStyle}" Source="picture1.png" Title="title 1"/>
How can I make those properties of children being settable in the parent?
A Button has indeed no Title or Source properties. If you don't want to create your own custom control, you should be able to use the Content and Tag properties:
<Button Style="{StaticResource myStyle}" Tag="picture1.png" Content="title 1"/>
Template:
...
<Image Width="300" Height="250" x:Name="picGraph"
Source="{Binding Tag, RelativeSource={RelativeSource AncestorType=Button}}" />

How can I make controls in WPF stretch to fill available width when HorizontalAlignment and HorizontalContentAlignment don't work?

I'm trying to make a simple WPF app that has sections that fill the available width. Despite trying various ways of stretching the width of elements, containers, and children, nothing is working and I can't figure out why.
Another question said to use uniformgrid which worked well EXCEPT that it set the height of all the elements uniformly which was definitely not what I wanted. I want all of the sections to look like the one in the picture - filled width, height auto based on the content. Here's the basic setup:
<Window x:Class="A_Customizer.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:A_Customizer"
mc:Ignorable="d"
Title="MainWindow"
Background="#FF2B2B2B"
Width="800"
>
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type CheckBox}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Name="mainApp" >
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" >
<Button ToolTip="Click to apply the below settings to this Jumpbox" Click="ApplyCustomizations">Customize</Button>
</WrapPanel>
<ScrollViewer Grid.Row="1">
<WrapPanel HorizontalAlignment="Stretch" >
<GroupBox
Background="#FFE2E2E2"
BorderBrush="#FF7F7F7F"
Margin="10,10,10,10"
Name="pathsBox"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
>
<GroupBox.Header>
<Border Background="#FFAFAFAF" CornerRadius="3">
<Label FontWeight="Bold">Key Paths</Label>
</Border>
</GroupBox.Header>
<StackPanel HorizontalAlignment="Stretch">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBox Name="homeFolder" Grid.Column="0" HorizontalAlignment="Stretch"></TextBox>
<Button Grid.Column="1" Click="NewQuickPath" ToolTip="Change home folder">
<Image Source="images\add_folder.png" Height="25" Cursor="Hand"></Image>
</Button>
</Grid>
<TextBox Name="progFolder" Grid.Column="0" HorizontalAlignment="Stretch"></TextBox>
</StackPanel>
</GroupBox>
<GroupBox
Background="#FFE2E2E2"
BorderBrush="#FF7F7F7F"
Margin="10,10,10,10"
Name="quickBox"
Height="auto"
HorizontalContentAlignment="Stretch"
>
<GroupBox.Header>
<Border Background="#FFAFAFAF" CornerRadius="3">
<Label FontWeight="Bold">Quick Access Folders</Label>
</Border>
</GroupBox.Header>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock TextWrapping="Wrap" Margin="15">
There are going to be folders you'll need to access frequently and keeping them pinned on top of the left menu in Explorer is helpful.
Select here to add them to the list of folders restored with the "Customize" button. Click any folder to remove it.
</TextBlock>
<Border CornerRadius="3" Background="#FFF3C7C7" Margin="6" Visibility="Collapsed" Name="quickErr" Tag="err_box">
<TextBlock Tag="errMsg" Foreground="#FFFD3434" TextWrapping="Wrap" Margin="6" ></TextBlock>
</Border>
<UniformGrid Name="quickPathsArea" Columns="1">
</UniformGrid>
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" HorizontalAlignment="Stretch"></TextBox>
<Button Grid.Column="1" Click="NewQuickPath" ToolTip="Add a new folder">
<Image Source="images\add_folder.png" Height="25" Cursor="Hand"></Image>
</Button>
</Grid>
</StackPanel>
</GroupBox>
</wrappanel>
</scrollviewer>
</grid>
StackPanel with Orientation="Vertical" (default value) instead of WrapPanel should work: it will allow each child element use full width and as much height as necessary

Default behavior of a textbox

I've got a custom control that is a textbox and two buttons inside a frame.
I'd like the frame to display the typical textbox border-behaviour. Currently, it just has a black border. Is there a short way or will I need 200 lines of XAML?
(I've found some examples e.g. the ComboBoxStyles-Example from MS, but .. these do use 200 lines of XAML).
This is the style for the IntegerSpinControl:
<Style TargetType="{x:Type cc:IntegerSpinControl}">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:IntegerSpinControl}">
<Border BorderThickness="1" BorderBrush="Black">
<DockPanel LastChildFill="True" HorizontalAlignment="Stretch">
<Grid DockPanel.Dock="Right" x:Name="grid1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RepeatButton Grid.Row="0"
Grid.Column="1"
Width="22"
Height="10"
Padding="0"
BorderThickness="0"
Command="{x:Static cc:IntegerSpinControl.IncreaseCommand}">
<RepeatButton.Content>
<Rectangle Width="16"
Height="5"
Fill="{StaticResource brush.scroll.up}" />
</RepeatButton.Content>
</RepeatButton>
<RepeatButton Grid.Row="1"
Grid.Column="1"
Width="22"
Height="10"
Padding="0"
BorderThickness="0"
Command="{x:Static cc:IntegerSpinControl.DecreaseCommand}">
<RepeatButton.Content>
<Rectangle Width="16"
Height="5"
Fill="{StaticResource brush.scroll.down}" />
</RepeatButton.Content>
</RepeatButton>
</Grid>
<TextBox DockPanel.Dock="Left"
BorderThickness="0"
HorizontalAlignment="Stretch"
Grid.Row="0"
Grid.Column="0"
Width="Auto"
Margin="0,0,1,0"
VerticalAlignment="Center"
IsReadOnly="True"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=FormattedValue,
Mode=OneWay}" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
There is already a control in the Extended WPF Toolkit that might be what you are looking for:
IntegerUpDown Control
Maybe you can use that instead?
BTW: There are also a Decimal and a Double version in the toolkit.
That being said, if you have to use your own Custom Control you will have to create the Templates and Styles yourself, however you can probably copy heavily from the Windows defaults.

How to make a custom tool tip template in WPF XAML

I have a number of buttons on a form (devcomponents ButtonDropDown controls to be precise).
I want to show a tool tip for each that contains a header at the top, an image on the left and a description on the right.
The header needs to be tied to the ButtonDropDown.Header, the image to the ButtonDropDown.Image. I also then need to define the description somewhere.
I've only been using WPF for a few weeks so I've not managed to find any answers via searching, though I have studied a few.
Below is my attempt at creating a template that really doesn't work at all:
<Style TargetType="dcr:ButtonDropDown">
<Setter Property="OverridesDefaultStyle" Value="True"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dcr:ButtonDropDown">
<ContentControl>
<ContentControl.ToolTip>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Content="{TemplateBinding Header}" FontWeight="Bold" />
<Viewbox Grid.Row="1" Grid.Column="0" Width="64" Height="32" Margin="3">
<ContentControl Content="{TemplateBinding Image}" />
</Viewbox>
<Label Grid.Row="1" Grid.Column="1"
Content="{TemplateBinding ToolTip.Content}" />
</Grid>
</ContentControl.ToolTip>
</ContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I then define a button as follows:
<dcr:ButtonDropDown Header="-X" Command="{Binding MoveCommand}" CommandParameter="xMinus"
ImagePosition="Top" IsEnabled="{Binding UserConfiguration.Move.Visible}"
ToolTip="move x axis down">
<dcr:ButtonDropDown.Image>
<Viewbox Width="32" Height="32" Margin="3">
<ContentControl Content="{StaticResource minusXImage}" />
</Viewbox>
</dcr:ButtonDropDown.Image>
</dcr:ButtonDropDown>
Please could someone give me an idea how to go about this?
I've gone some way to answering this question.
The following style is defined for ToolTip:
<Style TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToolTip}},
Path=PlacementTarget.(dcr:ButtonDropDown.Header)}"
FontWeight="Bold" />
<Viewbox Grid.Row="1" Grid.Column="0" Width="64" Height="32" Margin="3">
<ContentControl Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToolTip}},
Path=PlacementTarget.(dcr:ButtonDropDown.Image)}" />
</Viewbox>
<Label Grid.Row="1" Grid.Column="1"
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToolTip}},
Path=PlacementTarget.(dcr:ButtonDropDown.ToolTip)}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I then define a button as above and the ToolTip text and header appear in the ToolTipas required.
The key is the binding:
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToolTip}},
Path=PlacementTarget.(dcr:ButtonDropDown.Header)}"
Which finds the Tooltip as an ancestor of Label and casts its PlacementTarget into a ButtonDropDown
What doesn't work is the image. This appears in the ToolTip but is removed from the button.
This will also break any other controls' tooltips if they are not ButtonDropDown controls.
I'm beginning to think I'll need to create some custom controls that contain the information I require for the ToolTip for each control.

Categories

Resources