ControlTemplate not showing Grid - c#

I'm trying to create a Button that contains a grid, with rows that contain certain text.
The Button will have two rows, both with different pieces of text. The text that is passed to the ControlTemplate is showing, but not the text specified in the template.
Also, the heights of the Grid rows is not showing. I want it to expand the height of the button. In fact, I'm not sure that the Grid is showing at all really.
<Window x:Class="MAQButtonTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="695" Width="996">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
<ControlTemplate TargetType="Control" x:Key="1">
<Grid Width="444">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter Grid.Row="0" />
</Grid>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="#e9f1f6"></Grid>
<Grid Grid.Column="1" Background="#d2e3ed">
<StackPanel>
<TextBlock FontFamily="Segoe UI" FontSize="22" FontWeight="Medium" Margin="52,58,0,0" Foreground="#0c3d5d">Your Quizzes <TextBlock FontFamily="Segoe UI" FontSize="18" FontWeight="Medium" Foreground="#0c3d5d">(7)</TextBlock></TextBlock>
<Grid>
<Button Width="444" Background="{x:Null}" BorderThickness="0" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<TextBlock>This is a second piece of text</TextBlock>
</Button>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Window>
Here's how it shows at the moment with a rough illustration of what I'm trying to achieve as a button layout:

You're setting the Style of the Button, when you should be setting the Template
Resource:
<ControlTemplate TargetType="Button" x:Key="ButtonTemplate">
<Grid Width="444">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter />
</Grid>
</Grid>
</ControlTemplate>
And the button:
<Button Template="{StaticResource ButtonTemplate}" >
Text 2
</Button>

Why are you using TargetType as "Control", use Button. You will need to define a button. Use Blend to edit button template to strip all unnecessary content from it.

Related

Drag & Drap doesn't work with custom Window.Style

I have a simple UI made with wpf. In there is a Page containig a CustomControl with a TreeView. To reorder the TreeNodes i am using wpf dragdrop. This works pretty well so far. Now i'm playing around with WindowChrome to create a borderless window. But the Problem: Now Drag & Drop won't work. If i try to drag an object the curser changes into a "no valid drop position"
What i've found out: If i delete my custom evererything works. But i have now idea what is missing to get the drag and drop function working with my custom style.
The TreeView:
<TreeView x:Name="StructureTree"
Grid.Row="0"
Padding="10,20,20,0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Path=RootElement.Children}"
Background="{x:Null}"
BorderBrush="{x:Null}"
dd:DragDrop.IsDragSource="true"
dd:DragDrop.IsDropTarget="true"
dd:DragDrop.UseDefaultDragAdorner="true">
The Window.Resources:
<Window.Resources>
<Style TargetType="{x:Type local:MainWindow}" BasedOn="{StaticResource {x:Type Window}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<!-- Outer border with the dropshadow margin -->
<Border Padding="{Binding OuterMargin, FallbackValue=10}">
<!-- Main window outline -->
<Grid>
<!-- Opacity mask for corners on grid -->
<Border x:Name="Container"
Background="{StaticResource BackgroundVeryLightBrush}"
CornerRadius="{Binding WindowCornerRadius}" />
<!-- Window border and dropshadown -->
<Border CornerRadius="{Binding WindowCornerRadius}"
Background="{Binding BackgroundVeryLightBrush}" BorderBrush="#FF1E1E1E">
<Border.Effect>
<DropShadowEffect ShadowDepth="2" Opacity="0.2" BlurRadius="5" />
</Border.Effect>
<Border.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Container}" />
</Border.OpacityMask>
</Border>
<!-- The main window content -->
<Grid>
<!-- Corner clipping -->
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=Container}" />
</Grid.OpacityMask>
<Grid.RowDefinitions>
<!-- Title Bar -->
<RowDefinition Height="{Binding TitleHeight, FallbackValue=42}"/>
<!-- Window Content -->
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title Bar -->
<Grid Grid.Column="0" Grid.Row="0" Panel.ZIndex="1">
<Grid.ColumnDefinitions>
<!-- Icon -->
<ColumnDefinition Width="Auto"/>
<!-- Title -->
<ColumnDefinition Width="*"/>
<!-- Window Buttons -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Icon -->
<Button Margin="1" Padding="0" Style="{StaticResource IconButton}" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding MenuCommand}">
<!--<Image Source="/Images/Logo/Icon.ico"/>-->
</Button>
<!-- Title -->
<Viewbox Grid.Column="0" Grid.ColumnSpan="3" Margin="0">
<TextBlock Style="{StaticResource TitleText}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue= 'Wellcome'}"/>
</Viewbox>
<!-- Window Buttons -->
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Button Command="{Binding MinimizeCommand}" Style="{StaticResource WindowControlButton}" Content="_"/>
<Button Command="{Binding MaximizeCommand}" Style="{StaticResource WindowControlButton}" Content="[ ]"/>
<Button Command="{Binding CloseCommand}" Style="{StaticResource WindowCloseButton}" Content="X"/>
</StackPanel>
</Grid>
<!-- Page Content -->
<Border Grid.Row="1" Padding="{Binding InnerContentPadding}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
When I was experimenting with a similar scenario I found that WPF won't allow to drop an item if it can't detect a control under the cursor. The solution to this may be to add a stretched rectangle "under" your TreeView with transparent filling:
<Rectangle
Fill="Transparent"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<TreeView x:Name="StructureTree"...
Just so a control could be "under" your cursor and then you should get back your valid drop area.
Edit:
If it doesn't want to work, try to put the rectangle before this part in the template:
<!-- Opacity mask for corners on grid -->
<Border x:Name="Container"
Background="{StaticResource BackgroundVeryLightBrush}"
CornerRadius="{Binding WindowCornerRadius}" />
And since the basic window template uses AdornerDecorator, it's worth a shot to include in your template too, where needed:
<AdornerDecorator>
<ContentPresenter.../>
</AdornerDecorator>

Black Background occurs when using microsoft.windows.shell

I am using the microsoft.windows.shell to customize my wpf window chrome. Everything is fine until I added a datagrid. The problem is that the appearance of the window become black sometimes. This situation does not happen constantly! Sometimes it looks fine but sometimes it has a black background.
Here is my xaml code:
<Window x:Class="CodeGeneratorWpf.Config"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Config" Height="300" Width="300" Style="{StaticResource MainWindowStyle}"
WindowStartupLocation="CenterOwner" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<DataGrid Name="dataGrid" Grid.Row="0" ItemsSource="{Binding data}"
AlternatingRowBackground="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
ClipToBounds="True" VerticalGridLinesBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
HorizontalGridLinesBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
LoadingRow="dataGrid_LoadingRow">
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow},
Path=Header}"/>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
</DataGrid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Name="btnSave" Grid.Column="0" Content="Save" Style="{StaticResource EmphasizeButton}" HorizontalAlignment="Stretch" Margin="25,5,25,5" Click="btnSave_Click"/>
<Button Name="btnCancel" Grid.Column="1" Content="Cancel" Style="{StaticResource NormalButton}" Margin="25,5,25,5" Click="btnCancel_Click"/>
</Grid>
</Grid>
</Window>
The MainWindowStyle:
<!--Captions Buttons to control the window borderless-->
<DockPanel Grid.Row="0">
<DockPanel.Background>
<SolidColorBrush Color="#FF5D91DC"></SolidColorBrush>
</DockPanel.Background>
<Image Name="imgTitle" Source="{TemplateBinding Icon}" DockPanel.Dock="Left" Margin="5"></Image>
<Label Content="{TemplateBinding Title}" Foreground="White"></Label>
<ctrl:CaptionButtons Margin="0,0,0,0" Grid.Row="0" HorizontalAlignment="Right" Type="Full"
Foreground="{DynamicResource CaptionButtonColor}" FontSize="14" MarginButton="0,0,5,0"
VerticalAlignment="Center" shell:WindowChrome.IsHitTestVisibleInChrome="True">
</ctrl:CaptionButtons>
</DockPanel>
<ContentPresenter Margin="0" Grid.Row="1" Content="{TemplateBinding Content}"/>
</Grid>
</Border>
</ControlTemplate>
<Style x:Key="MainWindowStyle" TargetType="{x:Type Window}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="25"
CornerRadius="0"
GlassFrameThickness="0,0,0,1" />
</Setter.Value>
</Setter>
<Setter Property="Template" Value="{StaticResource MainWindowControlTemplate}"/>
</Style>
Can I get some help?

Stretch two buttons inside a WrapPanel

I am switching from Windows Forms to WPF and I would like to copy the GUI over. Since just running it through a converter gives horrible code I am giving it a go myself. Though when I try to create a simple groupbox, it already is giving me troubles.
I want to create this:
But I end up with this:
This is the XAML:
<GroupBox Header="Search" Width="200">
<StackPanel>
<TextBox />
<WrapPanel>
<Button Content="Reset" />
<Button Content="Search" />
</WrapPanel>
</StackPanel>
</GroupBox>
If I play around with HorizontalAlignment it doesn't do anything. I want to stretch the buttons (50% each) but I can't seem to find a way to get it done. I feel as if WrapPanel maybe isn't the right container here, but I can't find an alternative.
You can use the Grid container or the UniformGrid container.
Example 1 (Grid instead of WrapPanel):
<GroupBox Header="Search" Width="200">
<StackPanel>
<TextBox />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Reset" Margin="0,5,5,0" />
<Button Grid.Column="1" Content="Search" Margin="5,5,0,0" />
</Grid>
</StackPanel>
</GroupBox>
Example 2 (Grid for whole layout):
<GroupBox Header="Search" Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
<Button Grid.Row="1" Grid.Column="0" Content="Reset" Margin="0,5,5,0" />
<Button Grid.Row="1" Grid.Column="1" Content="Search" Margin="5,5,0,0" />
</Grid>
</GroupBox>
Example 3 (UniformGrid instead of WrapPanel):
<GroupBox Header="Search" Width="200">
<StackPanel>
<TextBox />
<UniformGrid Columns="2" Rows="1">
<Button Content="Reset" Margin="0,5,5,0" />
<Button Content="Search" Margin="5,5,0,0" />
</UniformGrid>
</StackPanel>
</GroupBox>
Result layout for all examples:
Useful links
MSDN: WPF Container Controls Overview
MSDN: Grid
MSDN: UniformGrid
CodeProject: WPF Tutorial : Layout-Panels-Containers & Layout Transformation
CodeProject: WPF Layouts - A Visual Quick Start
2,000 Things You Should Know About WPF: UniformGrid
Try this:
<GroupBox Header="Search" Width="200" >
<GroupBox.Resources>
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="4"></Setter>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
</GroupBox.Resources>
<StackPanel Margin="2">
<TextBox />
<UniformGrid Rows="1">
<Button Content="Reset" />
<Button Content="Search" IsDefault="True" />
</UniformGrid>
</StackPanel>
</GroupBox>

Create and switch between Edit / View Templates for a control

I have a TextBlock that dislays a message. I have to build the ability to edit and save this message. When the Edit Icon is clicked, instead of popping up another view with a TextBox and a Save Button, I wanted to somehow just show a Textbox and Save Button in place of the TextBlock. Then when Save is clicked it would change the State back again only showing the read only TextBlock.
I thought that I could do this with the VisualStateManager but it seems you can only do Storyboards for States and even if I leave the button always there and make it invisible I can't seem to change the Property Value between States either.
Is VisualStateManager the answer for this or is there something better to use?
Update
I found and followed this example View / Edit Control and it looks like it will solve my issue.
<UserControl x:Class="WpfApplication1.Test2"
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"
xmlns:c="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Name="MyTest" c:ReadOnlyControlTemplate.Enabled="True" c:ReadOnlyControlTemplate.DoLock="False" Grid.Column="0" Grid.Row="0" Content="{Binding Path=Message}" >
<Control.Template>
<ControlTemplate TargetType="{x:Type Label}">
<TextBox Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" AcceptsReturn="True" Margin="100,0" />
</ControlTemplate>
</Control.Template>
<c:ReadOnlyControlTemplate.LockTemplate>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="Red" BorderThickness="3">
<TextBlock Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" Foreground="White" />
</Border>
</ControlTemplate>
</c:ReadOnlyControlTemplate.LockTemplate>
</Label>
<WrapPanel Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center">
<Button Content="ReadOnly" Width="70" Height="25" Click="Button_Click" Margin="0,0,5,0" />
<Button Content="Edit" Grid.Column="0" Grid.Row="1" Width="50" Height="25" Click="Button_Click2" />
</WrapPanel>
</Grid>

Grid Border / Gap between cells

I've created a ControlTemplate that contains a Grid with two rows.
Sadly, there appears to be a single pixel gap between the cells.
How do I remove the gap?
Here's a screenshot showing the gap:
...and here's the XAML:
<Window x:Class="MAQButtonTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="695" Width="996">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
<ControlTemplate TargetType="Button" x:Key="ButtonTemplate">
<Grid Width="444" Margin="0" ShowGridLines="False">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter Grid.Row="0" />
</Grid>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="#e9f1f6"></Grid>
<Grid Grid.Column="1" Background="#d2e3ed">
<StackPanel>
<TextBlock FontFamily="Segoe UI" FontSize="22" FontWeight="Medium" Margin="52,58,0,0" Foreground="#0c3d5d">Your Quizzes <TextBlock FontFamily="Segoe UI" FontSize="18" FontWeight="Medium" Foreground="#0c3d5d">(7)</TextBlock></TextBlock>
<Grid Margin="0,20,0,0">
<Button Width="444" Background="{x:Null}" BorderThickness="0" Template="{StaticResource ButtonTemplate}" Click="DoSomething" BorderBrush="#032135">
<TextBlock Margin="6,2.8,0,0" FontFamily="Segoe UI" FontSize="19" Foreground="#032135" FontWeight="Medium">This is a second piece of text</TextBlock>
</Button>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Window>
Just add SnapsToDevicePixels="True" in your template grid
<ControlTemplate TargetType="Button" x:Key="ButtonTemplate">
<Grid Width="444" Margin="0" ShowGridLines="False" SnapsToDevicePixels="True">
<Grid.RowDefinitions>
<RowDefinition Height="51" />
<RowDefinition Height="36" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#286c97">
<TextBlock>This is the first piece of text</TextBlock>
</Grid>
<Grid Grid.Row="1" Background="#5898c0">
<ContentPresenter Grid.Row="0" />
</Grid>
</Grid>
</ControlTemplate>
Set
SnapsToDevicePixels="True"
On grids in template or button, but better just create new style with SnapsToDevicePixels="True" setter and template inside style.

Categories