Viewbox TabControl sizing gets messed up depending on font size - wpf

I have a program that lets you edit different properties so that you can edit a different control.
I'm trying to get the layout right for the editor but I can't seem to get it easily.
I have put it in a viewbox so it sizes according to the screen. This is the XAML for the editor:
<Viewbox Grid.Column="0" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Center">
<TabControl Background="{DynamicResource CustomOrange}">
<TabItem Header="Background" Visibility="Visible" FontSize="10">
<StackPanel>
<DockPanel LastChildFill="False">
<Label Content="Background" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30"/>
</DockPanel>
<DockPanel LastChildFill="False" Margin="2">
<Label Content="Background Image" DockPanel.Dock="Left"/>
<Button Content="Find Image" DockPanel.Dock="Right"/>
</DockPanel>
<DockPanel LastChildFill="False" Margin="2">
<Label Content="Show Text" DockPanel.Dock="Left"/>
<CheckBox Content="Find Image" DockPanel.Dock="Right" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DockPanel>
</StackPanel>
</TabItem>
<TabItem Header="Button" Visibility="Visible">
<StackPanel>
<DockPanel LastChildFill="False">
<Label Content="Background IMAGE" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30"/>
</DockPanel>
<DockPanel LastChildFill="False" Margin="2">
<Label Content="Background Image" DockPanel.Dock="Left"/>
<Button Content="Find Image" DockPanel.Dock="Right"/>
</DockPanel>
<DockPanel LastChildFill="False" Margin="2">
<Label Content="Show Text" DockPanel.Dock="Left"/>
<CheckBox Content="Find Image" DockPanel.Dock="Right" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DockPanel>
</StackPanel>
</TabItem>
</TabControl>
</Viewbox>
The problem is that the first TabItem looks like this:
But because I have changed the content of the label, the second TabItem looks like this:
Now, I know there are simpler ways to do this, but the problem is I don't know for sure how many options I am implementing for the user (Width, Height, Location, Font, Background, Content etc).
I have done it before with a grid but the problem is anytime I remove an option then all of them need to be re-done so that they are all in the exact Grid.Row which is why I am using StackPanel for the rows, and I am using the DockPanel so they keep separated horizontally
Thank you!!!

Related

WPF left button, centered text, right button in a custom control

I'm trying to prototype a new custom control that has a left button, text, and right button.
The XAML looks like this:
<StackPanel Width="250" Orientation="Vertical" >
<DockPanel Background="Azure" Width="250">
<Button Name="btnLeft" HorizontalAlignment="Left" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}">
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Previous25px.png" VerticalAlignment="Center" Name="imgLeft"></Image>
</StackPanel>
</Button>
<TextBlock Name="tblkModelType" HorizontalAlignment="Center" Foreground="Black" FontSize="20">Import</TextBlock>
<Button Name="btnRight" HorizontalAlignment="Right" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}" >
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Next25px.png" VerticalAlignment="Center" Name="imgRight"></Image>
</StackPanel>
</Button>
</DockPanel>
</StackPanel>
The buttons are left and right justified ok, but the (tblkModelType) is left justified right up next to the left button. It doesn't appear that HorizontalAlignment on that tag does anything. If I remove the right button, the TextBlock does center.
Anyone know how to get the buttons on the outside and the TextBlock centered in the Dockpanel? I guess I could use a grid, but it would make the rest of the control more complex.
This should work:
<DockPanel Background="Azure" Width="250" >
<Button DockPanel.Dock="Left" Name="btnLeft" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}">
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Previous25px.png" VerticalAlignment="Center" Name="imgLeft"></Image>
</StackPanel>
</Button>
<Button DockPanel.Dock="Right" Name="btnRight" Width="30" Background="DarkGray" Click="btnAdd_Click" Template="{DynamicResource StandardButtonTemplate1}" >
<StackPanel Orientation="Horizontal">
<Image Source="/Images/Next25px.png" VerticalAlignment="Center" Name="imgRight"></Image>
</StackPanel>
</Button>
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Center" Name="tblkModelType" Foreground="Black" FontSize="20">Import</TextBlock>
</DockPanel>
Use DockPanel.Dock to dock btnLeft to the left of the DockPanel, btnRight to the right. Then for tblkModelType set DockPanel.Dock="Top". This will stretch the TextBlock to the entire width of the DockPanel between buttons.
This works for me. As you said your control is more complex, so in case of any problem share more xaml with us.

Event on ItemsControl issue [duplicate]

I`ve created big button which contains grid as below:
<Button Height="Auto" Width="Auto" Command="{Binding ContinueWithoutScan}" BorderThickness="0">
<Button.Template>
<ControlTemplate>
<Grid >
<TextBlock HorizontalAlignment="Center"
TextWrapping="Wrap" Text="Text"
VerticalAlignment="Center" FontWeight="DemiBold"
Height="Auto" Width="Auto"
FontSize="25" Foreground="White"/>
<materialDesign:PackIcon Height="Auto" Width="70" Kind="ChevronRight" Foreground="White"
VerticalAlignment="Center" HorizontalAlignment="Right"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
There is problem that only TextBlock inside Template is clickable. Does anyone know how do I make whole content clickable? I working with MVVM so I dont want make Grid.OnMouseEneter.
Is there option to do that of I have to use EventTriggers?
The Grid needs to have a Background other than the default null to receive input events. You may set a transparent background instead of null:
<Grid Background="Transparent">
...
</Grid>

Put TextBlock on top of another TextBlock

I tried to implement case in which one TextBlock appears on top of another TextBlock, playing with Visibility property - but it doesn't working yet.
TextBlock are inside DockPanel:
<DockPanel Grid.Row="1" Margin="5">
<TextBlock Text="Text1" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right">
<TextBlock Text="Text2" Background="Aqua" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding IfDeviceSelected, NotifyOnSourceUpdated=True, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}" />
</TextBlock>
<TextBlock Text="#Device Focus:" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right" />
</DockPanel>
You will want to use a Grid to group these TextBlocks, DockPanel/StackPanel will not allow overlapping controls(without horrible manipulation of Margins etc)
<DockPanel Grid.Row="1" Margin="5" >
<Grid DockPanel.Dock="Right" >
<TextBlock Text="Text1" />
<TextBlock Text="Text2" Background="Aqua" Visibility="{Binding IfDeviceSelected, NotifyOnSourceUpdated=True, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}" />
</Grid>
<TextBlock Text="#Device Focus:" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right" />
</DockPanel>

Why is my dockpanel's LastChild overflowing its container?

I have a DockPanel with LastChildFill = true. It has 4 children: a StackPanel(top), another DockPanel(top), and three more StackPanels(bottom, left & none respectively). The last StackPanel ("ResultsPanel") has no DockPanel.Dock property set, nor does it have a width/height, yet when the databinding results in more rows than fit on the screen, it continues down behind the bottom-docked StackPanel. I would expect it to fill the center "hole" that I left between the other docked children.
If I leave the ScrollBarVisibilities set to Auto, it doesn't even show them. Any advice would be appreciated. Here is the pertinent code:
<DockPanel Name="JobsDock" LastChildFill="True">
<StackPanel DockPanel.Dock="Top" Height="40" >
<Label />
<Border CornerRadius="5" Width="90" Height="25" >
<Label Content="Classic View" />
</Border>
</StackPanel>
<DockPanel DockPanel.Dock="Top" Height="70" Name="SearchJobsPanel" >
<ComboBox Name="SearchOptionComboBox" VerticalAlignment="Bottom" Width="240" />
<StackPanel Height="50" Name="JobPanel" Width="90" Visibility="Collapsed" VerticalAlignment="Bottom" >
<Label Content="Job Number" HorizontalAlignment="Center" />
<TextBox Name="JobTextBox" />
</StackPanel>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Right">
<Button Height="25" Name="SearchButton" Width="90">
<StackPanel Orientation="Horizontal">
<Image Stretch="Fill" Margin="0,0,5,0" />
<Label Content="Search" FontSize="10" VerticalContentAlignment="Top" />
</StackPanel>
</Button>
</StackPanel>
</DockPanel>
<StackPanel Name="FiltersPanel" DockPanel.Dock="Left" Width="120" Opacity="0" >
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Name="ResetFilterButton" >
<Image Source="Images/ResetFilter.png" Width="30" />
</Button>
<Button Name="ApplyFilterButton" >
<Image Width="30" />
</Button>
</StackPanel>
<Label Name="ProjectsLabel" />
<Label Name="TasksLabel" Margin="0,10,0,0" />
</StackPanel>
<StackPanel Name="ResultsPanel" Opacity="0">
<ListView x:Name="DisplayedJobListView" ScrollViewer.VerticalScrollBarVisibility="Visible" >
<ListView.View>
<GridView>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
Jurgen, on the msdn forum answered this question for me. Here is his reply:
Hi,
the last (filling) DockPanel child is a StackPanel ("ResultsPanel"). A StackPanel's layout is never defined by containing controls (there is nothing working like VerticalLayout="Stretch" for a StackPanel). It will always take the space neccessary for it's contained controls to fully expand.
As you only have one child in that StackPanel (which has a scrolling mechanism of it's own) remove the StackPanel.
Hope this helps.
Cheers
Jürgen

Align label to the middle of dock panel

I have a dock panel, with one label in the middle and another button on the far right.
Because of the button the label cannot align to the middle when the windows is maximized.
WPF:
<DockPanel Height="40" HorizontalAlignment="Stretch" Margin="-1,-2,0,0" Name="dockPanel1" VerticalAlignment="Stretch" Width="Auto" OpacityMask="{x:Null}">
<Label FontSize="18" Content="Sales" FontWeight="Bold" FontFamily="Arial" Width="883" Height="42" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Foreground="White" DockPanel.Dock="Left" VerticalAlignment="Center" VerticalContentAlignment="Center"></Label>
<Button FontSize="18" Height="47" Width="123" Name="btnStart" Foreground="White" BorderBrush="{x:Null}" FlowDirection="LeftToRight" HorizontalContentAlignment="Center" FontFamily="Arial Rounded MT" ClickMode="Press" DockPanel.Dock="Right" HorizontalAlignment="Right" VerticalAlignment="Center" Padding="0" Content="Start" BorderThickness="0" Focusable="False">
</DockPanel>
Use a Grid instead of a DockPanel
Grid's allow objects to be placed on top of each other, so you can position your Label in the middle and the Button on the Right
<Grid>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button HorizontalAlignment="Right" />
</Grid>
Also if you're new to WPF's Layouts, I'd recommend reading through WPF Layouts: A Quick Visual Start so you know what layouts are available and can pick the best one for your sitaution

Resources