Templates and inheritance - wpf

I have a big problem.
I use additional controls for Wpf. One of them is Telerik RadWindow
This control is already templated.
Now I want to create custom Window with will inherit from RadWindow, and make custom template, eg. One base window will contains grid and two buttons, second base window will contain two grids (master - detail).
The problem is that templates do not support inheritance. Perhaps is another way to template only the content of Winodow?
My code, that doesn't work (empty window appears, so template doesn't apply)
<Style TargetType="{x:Type local:TBaseRjWindow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TBaseRjContent}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid Name="mGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition MaxHeight="40" MinHeight="30" />
<RowDefinition MaxHeight="40" MinHeight="30" />
<RowDefinition Height="Auto" />
<RowDefinition MaxHeight="40" MinHeight="30" />
</Grid.RowDefinitions>
<telerik:RadGridView Margin="10,10,10,10" Name="grid" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ScrollMode="Deferred" AutoGenerateColumns="False" Width="Auto" >
</telerik:RadGridView>
<telerik:RadDataPager Grid.Row="1" Grid.Column="0"
x:Name="radDataPager"
PageSize="50"
AutoEllipsisMode="None"
DisplayMode="First, Previous, Next, Text"
Margin="10,0,10,0"/>
<StackPanel Grid.Row="1" Grid.Column="0" Margin="5 5 5 5" HorizontalAlignment="Left" Orientation="Horizontal" Height="20" Width="Auto" VerticalAlignment="Center" >
<telerik:RadButton x:Name="btAdd" Margin="5 0 5 0" Content="Dodaj" />
<telerik:RadButton x:Name="btEdit" Margin="5 0 5 0" Content="Edytuj" />
<telerik:RadButton x:Name="btDelete" Margin="5 0 5 0" Content="Usun" />
</StackPanel>
<StackPanel Name="addFields" Background="LightGray" Visibility="Collapsed" VerticalAlignment="Top" Grid.Row="2" Grid.Column="0" Width="Auto" Height="Auto" Orientation="Horizontal">
<GroupBox Header="Szczegoly" Margin="2 2 2 2" >
<Grid VerticalAlignment="Top" DataContext="{Binding SelectedItem, ElementName=grid}" Name="_gAddFields" Margin="0 0 0 0" Width="Auto" Height="Auto" >
</Grid>
</GroupBox>
</StackPanel>
<StackPanel Grid.Row="3" Grid.Column="0" Margin="5 5 5 5" HorizontalAlignment="Right" Orientation="Horizontal" Height="25" Width="Auto" VerticalAlignment="Center" >
<telerik:RadButton x:Name="btSave" IsDefault="True" Width="60" Margin="5 0 5 0" Content="Zapisz" />
<telerik:RadButton x:Name="btOK" IsDefault="True" Width="60" Margin="5 0 5 0" Content="Akceptuj" />
<telerik:RadButton x:Name="btCancel" IsCancel="True" Width="60" Margin="5 0 5 0" Content="Anuluj" />
</StackPanel>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Please help

You could use the ContentTemplate for the Window. It is a DataTemplate that will be used to display the Content set on the Window.

Related

Can we use multi xaml layout on a window?

I think that we can use multi layout on a windows with XAML.
So I try to create a window like this:
I want to create an ListView in left and it can be resized. The Grid and Textbox at the left side will be fit to the right grid.
I have tried to use other layouts, StackPanel, DockPanel.
How can I create a resizable grid
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ToolBar Name="toolBar" Grid.Row="0">
<Button Name="btnLoad" Width="Auto" Height="25" ToolTip= Click="btnLoad_Click" VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/reload.png" Width="16" Height="16" HorizontalAlignment="Left" Margin="0 0 5 0"/>
<TextBlock>Load/Reload</TextBlock>
</StackPanel>
</Button>
<Button Name="btnSave" Width="Auto" Height="25" Click="btnSave_Click">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/save.png" Width="16" Height="16" HorizontalAlignment="Left" Margin="0 0 5 0"/>
<TextBlock>Save</TextBlock>
</StackPanel>
</Button>
</ToolBar>
<ComboBox Name="cbTypeOfShop" Grid.Row="1" Margin="5 5 5 5"/>
<Grid Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<GridSplitter Grid.Column="1" Grid.RowSpan="3" HorizontalAlignment="Left" VerticalAlignment="Stretch" Background="Black" ShowsPreview="true" Width="5"/>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGrid Name="dtgListItem" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</DataGrid>
<TextBox Grid.Row="1" Height="100" TextWrapping="Wrap" AcceptsReturn="True" Text="1231231231 22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222221231231231231231123123123123123123123123123123123123123123123123123" />
</Grid>
</Grid>
<StatusBar Grid.Row="3" Height="25" HorizontalAlignment="Stretch">
<TextBlock Name="abc">abc</TextBlock>
</StatusBar>
</Grid>
But when I resize the left side.
try this
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Left side</TextBlock>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<TextBlock Grid.Column="2" FontSize="55" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap">Right side</TextBlock>
</Grid>
As you can see, I've simply created a Grid with two equally wide columns, with a 5 pixel column in the middle.

Trying to get my Expander to resize with frame control

I am creating a XAML page that loads inside of a Frame control. It included an Expander control. I need for the Expander and all contents of the Expander to resize horizontally as the user resized the window. Does anyone have any suggestions, please?
<Grid>
<StackPanel x:Name="Stackpanel1" HorizontalAlignment="Stretch" Margin="8,8,0,10" Orientation="Horizontal" VerticalAlignment="Stretch">
<Expander ExpandDirection="Right" IsExpanded="True" Expanded="Expander_Expanded">
<Expander.Header>
<TextBlock Text="Daily" RenderTransformOrigin=".5,.5">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<StackPanel Orientation="Vertical"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Margin="8,0,16,0" Height="610">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Width="Auto">
<materialDesign:Card Grid.Column="1" Padding="5" UniformCornerRadius="8" Margin="0,5,0,0" >
<StackPanel Orientation="Horizontal"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Margin="8,24,16,24">
<TextBox x:Name="txtReprint" MinWidth="300"/>
<Button x:Name="btnReprint" Content="Re-Print" Margin="10,0,0,0" Width="156" Click="btnReprint_Click"/>
</StackPanel>
</materialDesign:Card>
</Grid>
<materialDesign:Card Grid.Column="0" Grid.Row="1" Padding="5" UniformCornerRadius="8" Margin="0,5,0,0" VerticalAlignment="Top" Height="508">
<StackPanel Orientation="Vertical"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Margin="8,0,16,0" VerticalAlignment="Top">
<Label x:Name="lblPriority" Content="Priority" VerticalAlignment="Top"/>
<DataGrid x:Name="dgvPriority" Width="467" Height="414"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnPriorityRefresh" Content="Refresh" Grid.Column="0" Margin="5,10,5,0" Click="btnPriorityRefresh_Click"/>
<Button x:Name="btnPriorityPrint" Content="Print" Grid.Column="1" Margin="5,10,5,0" Click="btnPriorityPrint_Click"/>
</Grid>
</StackPanel>
</materialDesign:Card>
<materialDesign:Card Grid.Column="1" Grid.Row="1" Padding="5" UniformCornerRadius="8" Margin="5,5,0,0" VerticalAlignment="Top" Height="508">
<StackPanel Orientation="Vertical"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Margin="8,0,16,0" VerticalAlignment="Top">
<Label x:Name="lblGround" Content="Ground" VerticalAlignment="Top"/>
<DataGrid x:Name="dgvPGround" Width="467" Height="414" HorizontalAlignment="Stretch"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnGroundRefresh" Content="Refresh" Grid.Column="0" Margin="5,10,5,0" Click="btnGroundRefresh_Click"/>
<Button x:Name="btnGroundPrint" Content="Print" Grid.Column="1" Margin="5,10,5,0" Click="btnGroundPrint_Click"/>
</Grid>
</StackPanel>
</materialDesign:Card>
</Grid>
</StackPanel>
</Expander>
<Border Background="{DynamicResource MaterialDesignDivider}" Width="1" VerticalAlignment="Stretch" SnapsToDevicePixels="True" />
<Expander ExpandDirection="Right" Expanded="Expander_Expanded">
<Expander.Header>
<TextBlock Text="Special Projects" RenderTransformOrigin=".5,.5">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<materialDesign:Card Grid.Column="1" Grid.Row="1" Padding="5" UniformCornerRadius="8" Margin="5,5,5,5" VerticalAlignment="Top" Height="603">
<StackPanel Orientation="Vertical"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"
Margin="8,24,16,3">
<Label x:Name="lblSpecialProjects" Content="Special Projects"/>
<DataGrid x:Name="dgvNAB" Width="467" Height="477" Margin="0,5,0,0"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnNABRefresh" Content="Refresh" Grid.Column="0" Margin="5,10,5,0" Click="btnNABRefresh_Click"/>
<Button x:Name="btnNABPrint" Content="Print" Grid.Column="1" Margin="5,10,5,0" Click="btnNABPrint_Click"/>
</Grid>
</StackPanel>
</materialDesign:Card>
</Expander>
</StackPanel>
</Grid>
Instead of a StackPanel you could use a Grid and create columns. Each Expander you put in a separate column and that way you can make them adjust according to the window size.

Listbox last element incorrect rendering

I got trouble with the listbox. Please, check the screenshot down there. The last element is kind of "eaten" by the listbox external border (I defined appropriate MaxHeight). Can someone help me?
<DataTemplate x:Key="QCTemplate">
<Grid>
<Expander x:Name="expander" Header="{Binding}">
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBox Name="ComponentNameTextBlock" Style="{StaticResource BorderlessTextBoxStyle}" Text="{Binding ComponentName, Mode=TwoWay}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="1">Количество цитат:</TextBlock>
<TextBlock Name="ComponentVolumeTextBlock" Grid.Column="1" Margin="1" Text="{Binding Volume}" />
</Grid>
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
<!-- Контекстное меню экспандера -->
<Expander.ContextMenu>
<ContextMenu>
<MenuItem Header="Оригинал 'My Clippings.txt'">
<MenuItem Header="Удалить из оригинала..."
Command="{StaticResource ResourceKey=DeleteFromMyClippingsCommand}"
CommandParameter="{Binding}" />
</MenuItem>
</ContextMenu>
</Expander.ContextMenu>
<!-- Внутреннее содержание экспандера -->
<Grid Name="ExpanderContentContainer"
Height="{Binding ElementName=ComponentChildsListBox, Path=ActualHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0"
Width="2" Height="{Binding Path=ActualHeight}"
Fill="Black"
Margin="2"
/>
<StackPanel Orientation="Vertical"
Grid.Column="1" Grid.Row="0">
<TextBox Name="ComponentCommentTextBox"
Text="{Binding Comment, Converter={StaticResource ResourceKey=QCCCommentConvrtr}, Mode=TwoWay}"
BorderThickness="0"
GotFocus="ComponentCommentTextBox_GotFocus"
Margin="1"
/>
<ListBox Name="ComponentChildsListBox"
BorderBrush="Transparent"
ItemsSource="{Binding ChildsCollection}"
ScrollViewer.CanContentScroll="False"
MaxHeight="300"
Margin="1"
Style="{StaticResource LibraryViewListBoxStyle}"
/>
</StackPanel>
</Grid>
</Expander>
</Grid>
</DataTemplate>
Screenshot

Separate TreeViewItem in few parts xaml wpf

How can separate TreeViewItem in few parts with Grid.Column or anything else to like in the picture: One part to be Label, second part to be Image, third part to be empty place and last part to be CheckBox (for example).
enter image description here
And my results is too different from this what I need to make, here is the picture with my results.
enter image description here
And part of my code:
<Border Name="SensorsOption" BorderThickness="0 2 2 2" BorderBrush="#dce3e2" Background="#dce3e2" Grid.Column="0" Grid.Row="3" Grid.RowSpan="2" Margin="0 2 0 0">
<ScrollViewer>
<Border Name="InsideSensorOption" BorderThickness="2 0 2 2" BorderBrush="#dce3e2" Background="#dce3e2" Grid.Column="0" Grid.Row="3" Grid.RowSpan="2">
<StackPanel Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible">
<Label Content="Sensors"
Background="#ebf0f0"
Foreground="#1d2326"
FontWeight="Bold"
FontSize="12"
BorderBrush="#dae3e2"
BorderThickness="0 0 0 2"
Padding="25 6 6 6"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="21*" />
<ColumnDefinition Width="43*" />
<ColumnDefinition Width="17*" />
<ColumnDefinition Width="15*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50*" />
<RowDefinition Height="50*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Source="https://cdn0.iconfinder.com/data/icons/good-weather-1/96/weather_icons-64-32.png" Height="24" Width="24" />
<Label Grid.Column="1" Grid.Row="0" Content="T1 S1" />
<CheckBox Grid.Column="3" Grid.Row="0" VerticalAlignment="Center" IsChecked="{Binding AirIsChecked}" />
<TreeView Grid.Row="1" Grid.ColumnSpan="4">
<TreeViewItem>
<TreeViewItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="68*" />
<ColumnDefinition Width="13*" />
<ColumnDefinition Width="19*" />
</Grid.ColumnDefinitions>
<Label Content="Value" Grid.Column="0" />
<Image Grid.Column="1" Source="http://www.metalsaber.com/images/main_images/rss.gif" Width="30" Height="15" />
<CheckBox Grid.Column="2" IsChecked="{Binding AirValueIsChecked}" />
</Grid>
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
</Grid>
</StackPanel>
</Border>
</ScrollViewer>
</Border>
It is possible by using Margin property:
<TreeView >
<TreeViewItem>
<TreeViewItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="68*" />
<ColumnDefinition Width="13*" />
<ColumnDefinition Width="19*" />
</Grid.ColumnDefinitions>
<Label Content="Value" Grid.Column="0" />
<TextBlock Text="Hello" Margin="100,0,0,0" Grid.Column="1"/>
<CheckBox Grid.Column="2" IsChecked="{Binding AirValueIsChecked}" />
</Grid>
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
As MSDN says:
The margin is the space between this element and other elements that
will be adjacent when layout creates the user interface (UI). Shared
elements might be peer elements (such as other elements in the
collection of a common parent control), or might also be this
element's parent.

WPF negative margins are not displayed correctly

I am trying to simulate a tab control with a nice TabHeader and TabContent. The control should look something like this:
This is achieved by setting the `Margin' of the first Header - "HOME" to Margin="2 0 2 -1".
ISSUE: if I re-size the window to a certain smaller width, the header item visually clips its content. Here is the result:
I really would like to know why this is happening and how ca i avoid this.
The sample xaml to prove the problem:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="550" Width="525">
<Grid Margin="0 50">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="Black" Grid.Row="1"/>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Border Width="50" Margin="2 0 2 -1" BorderThickness="1 1 1 0" BorderBrush="Black" Background="White">
<TextBlock Text="HOME" />
</Border>
<Border Width="150" Margin="2 -20" Height="20" BorderThickness="1 1 1 0" >
<TextBlock Text="EDIT" />
</Border>
</StackPanel>
</Grid>
When you resize the window, XAML renderer redraw any flexible (still can be resized or moved relatively). when you reach the StackPanel width limit (limited by what it contains or a fixed Width) the control is ignored at redrawing (even what it contains) and the renderer keeps redrawing other flexible controls; in your case : the first border. that's why comes suddenly on the top of the others.
Moving the margin to the StackPanel will do the trick :
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="2 0 2 -1">
<Border Width="50" BorderThickness="1 1 1 0" BorderBrush="Black" Background="White">
<TextBlock Text="HOME" />
</Border>
<Border Width="150" Height="20" BorderThickness="1 1 1 0" >
<TextBlock Text="EDIT" />
</Border>
</StackPanel>
Here is a solution with 2 columns
<Grid Margin="0,50">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="Black" Grid.Row="1" />
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Border Width="50" Margin="2,0,2,-1" BorderThickness="1,1,1,0" BorderBrush="Black" Background="White">
<TextBlock Text="HOME" />
</Border>
<Border Width="50" Margin="2" Height="20" BorderThickness="1,1,1,0" >
<TextBlock Text="EDIT" />
</Border>
</StackPanel>
</Grid>
This makes the grid not get clipped by the window size.
EDIT added additional column to push the border to the edge.
Cheers,
Eric
I would theorize that this is an oddity in the layout code of StackPanel. You should be able to work around it by moving the negative margin to the StackPanel itself, as opposed to the tabs within:
<Grid Margin="0 50" UseLayoutRounding="True">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderThickness="1" BorderBrush="#7FFF0000" Grid.Row="1" />
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,-1">
<Border Width="50" Margin="2 0 2 0" BorderThickness="1 1 1 0" BorderBrush="Lime" Background="Yellow">
<TextBlock Text="HOME" />
</Border>
<Border Width="150" Margin="2 0 2 0" Height="20" BorderBrush="Blue" BorderThickness="1 1 1 0" Background="Yellow">
<TextBlock Text="EDIT" />
</Border>
</StackPanel>
</Grid>
Note that I changed the colors to assist with visual debugging. It's a useful technique, but you'll probably want to change them back :).

Resources