XAML: Grid Cell Overflow - c#

I am trying to figure out a way that I can layout some text in a Grid, and have the contents of each cell overflow their borders. However it seems that I can't get this to happen, and I was hoping someone knew what to do about it.
Here is an example of some code. You can see that I included some 'ClipToBounds' properties to no avail. The layout is the same with or without them. Is what I am trying to do even possible?
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid ClipToBounds="False">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock FontSize="50" Text="proper queen jelly" Margin="50,50,0,0" ClipToBounds="False"/>
</Grid>
</Window>
I guess it is also worth mentioning that I will eventually attempt to port the app so that it is compatible with "Windows Store Apps" in the near future. I know there are some slight differences between that and WPF, so I guess I was wondering how this would work for both.

I'm not sure if I got your point, but perhaps you are looking for the Grid.RowSpan attribute. Your textblock will look like this:
<TextBlock Grid.RowSpan="2" FontSize="50" Text="proper queen jelly" Margin="50,50,0,0" ClipToBounds="False"/>

Related

UWP User Controls and Default Values

I am trying to create an UWP User Control for the first time. One very basic thing I want is automatic Width and Height at DESIGN-TIME and RUN-TIME based on the content of the user control. Simple enough in theory, but whenever I build the control and drop it on a form, it has this default "Width=100" value. Same thing with the Height.
Here is the simple XAML code i have so far:
<UserControl
x:Class="JTE.JTreeItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:JTE"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="Auto"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="10,32,0,0" Text="TextBlock" TextWrapping="Wrap" VerticalAlignment="Top"/>
</Grid>
</UserControl>
But when I drag the control from the toolbox to a page this is what I get:
<local:JTreeItem HorizontalAlignment="Left" Height="100" Margin="247,305,0,0" VerticalAlignment="Top" Width="100"/>
Both the Width and the Height are 100 by default. But why? How can I change this? This seems so simple, yet adding:
Width="Auto"
Does not solve this. Removing it does not solve it. Any value I put there gets ignored, for example, if I do this:
Width="199"
Nothing happens. I get the same 100 default value for the Width and the Height.
Why is this so not intuitive? There seems to be no syntax errors in the XAML, so what is happening there?
I am using Visual Studio Community 2019.
If any of you can help, I would appreciate it. Thanks in advance!!!
EDIT: Added a few things for clarity.

how to make wpf webview scroll like webbrowser?

I'm trying to use a Microsoft.Toolkit.Wpf.UI.Controls.WebView control in a wpf desktop application. It seems to use substantially less resouces than the webbrowser control and is much more up to date, being based on edge. However, unlike the webbrowser control, it won't scroll unless selected. i.e. When the mouse is over the webbrowser I can scroll up and down without selecting first but webview ignores the mouse wheel if it isn't the current selected control.
Using VS2019 the following code demonstrates the problem.
<Window x:Class="test0.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
Title="MainWindow" Height="600" Width="1024">
<Grid>
<StackPanel>
<Button Content="hello world" Height="100" />
<WPF:WebView Source="https://bing.com" Height="250" />
<WebBrowser Source="https://bing.com" Height="250" />
</StackPanel>
</Grid>
</Window>
On running, both browser controls will scroll when the mouse cursor is over. After clicking the button (removing the focus from either of the browsers), only the webbrowser control scrolls on mouseover.
Is there any workaround to fix this?
Using: .NET Framework 4.7.2 and Microsoft.Toolkit.Wpf.UI.Controls.WebView 5.1.1
Problem solved! But nothing to do with VS, or framework versions etc. It seems the touchpad driver doesn't play nice with the webview control under some circumstances. It was remiss of me not to mention I was using a touchpad vs a genuine mouse but it never occurred to me there would be a difference. Until I plugged in a mouse and there was no problem.
Anyway, the solution was to download and install precision touchpad drivers as per:
https://www.windowscentral.com/how-enable-precision-touchpad-drivers
Which solved the problem... Until windows decided to "update" the driver back to the old one. The only way to stop windows doing this was to disable "Automatic driver downloads" as per:
https://www.laptopmag.com/articles/disable-automatic-driver-downloads-on-windows-10
I wish I had mentioned I was using a touchpad as I suspect the problem might have been more easily reproducible for those who aren't using precision touchpad drivers.
I have created a sample page and also give code in the answer as per your requirement please review existing code and get back to me if there are any queries.
<Window x:Class="WpfApp1.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:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="720" Width="1280">
<Grid>
<StackPanel>
<Button Content="hello world" Height="100" />
<!--<WPF:WebView Source="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8" Height="250" />-->
<WPF:WebView Source="https://bing.com" Height="250" />
<WebBrowser Source="https://bing.com" Height="250"/>
</StackPanel>
</Grid>
Bing is a one view site so the search panel is not able to scroll even if you can directly check in on web browser.
Edit:
Can you please check your windows version and SDK as per requirements
https://learn.microsoft.com/en-us/uwp/api/windows.web.ui.interop.webviewcontrol
Windows version: 1809
SDK version: 17763
Added values:
AddInitializeScript
GotFocus
LostFocus
I do believe this is what you're looking for.
You'll want to define Row Definitions for your Grid as you see below and assign the what I assume is going to be your toolbar with "hello world" into Grid Row 0 and your web browser into Grid Row 1 rather than using the Stack Panel in this scenario (see code below).
Let me know if that helps or if you need it done a little differently I'm sure I could help you figure that out.
Grid Row Definitions - Microsoft Docs
<Window x:Class="WpfApp1.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:WPF="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls.WebView"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Content="hello world" Height="100" Grid.Row="0"/>
<WebBrowser Source="https://bing.com" Grid.Row="1"/>
<WPF:WebView Source="https://bing.com" Grid.Row="2"/>
</Grid>
</Window>
I have read your query and try to figure out some issues. Kindly check your windows and SDK version HERE.
Your windows version must have above or 1809
Your SDK version must have above or 17763
Please let me know in case any doubt or confusion.

Why DataBinding is not propagating to UserControl

This morning I asked a question here and doing a simple working sample gave me a different behavior than expected.
Full working sample at GitHub. Main partial code below.
In this present case, the command is never propagated to any UserControl, either if the UserControl is use directly as a child of the Window. It also not work if the UserControl is used as a DataTemplate for a ListBox ItemTemplate.
I also include a hack button to fix the problem where the Command reach the UserControls. The hack come from StackOverflow.
But using the hack does not explain why UserControl does not receive the Command (without it) and using this hack also break the first rule of good coding: "Hi cohesion and Low coupling". The hack should be used in the the window code in order for it to manage the Command in the UserControl, my thought is that it should happen by default.
Why the command is not propagating by default to the UserControl and what should I do to propagate the command to the UserControl in a clean way?
Note: Using only one CommandBinding (removing one or the other) in the UserControl does not fix the problem .
Partial code:
<Window x:Class="CommandRoutingIntoItemTemplate.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:CommandRoutingIntoItemTemplate"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<local:UserControlTest></local:UserControlTest>
<ListBox Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Aqua" BorderThickness="2">
<local:UserControlTest></local:UserControlTest>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Items>
<system:String>1</system:String>
<system:String>2</system:String>
</ListBox.Items>
</ListBox>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button Command="local:Commands.CommandTest">Put focus on TestBlock and click here to see if command occurs</Button>
<Button Click="AddHack">Hack</Button>
</StackPanel>
</Grid>
</Window>
UserControl:
<UserControl x:Class="CommandRoutingIntoItemTemplate.UserControlTest"
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:local="clr-namespace:CommandRoutingIntoItemTemplate"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="local:Commands.CommandTest" CanExecute="CommandTestCanExecuteUserControl" Executed="CommandTestExecuteUserControl"></CommandBinding>
</UserControl.CommandBindings>
<Grid>
<TextBox Text="UserControlTest">
<TextBox.CommandBindings>
<CommandBinding Command="local:Commands.CommandTest" CanExecute="CommandTestCanExecuteTextBox" Executed="CommandTestExecuteTextBox"></CommandBinding>
</TextBox.CommandBindings>
</TextBox>
</Grid>
</UserControl>
The reason that you are not getting commands invoked on your user control is that your buttons are not in separate focus scope. For WPF to pick up focused element for command target correctly, it needs to be in separate focus scope from command invoking control.
Framework will just traverse up visual tree from button looking for command bindings in their focus scope (in your case it won't find any). When framework does not find any command bindings in current focus scope, only then it looks into parent focus scope for focused element (In your case, buttons are in Window focus scope which has no parent scope so the search will end there).
Simply setting FocusManager.IsFocusScope="True" on your StackPanel will fix the issue.
You could also specify CommandTarget property on your buttons to point to your user control and not rely on focus.

Changing BackGround color of combobox when ItemsSource is set

I have a wpf c# app.
I am using a combo box and I set the ItemsSource to my Observable collection.
what I would like is the background of the combo box not to be grey.
This control is housed in a UserControl.
<UserControl x:Class="InformedWorkerClient.UserControls.ucJobStatus"
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:local="clr-namespace:InformedWorkerClient.UserControls"
mc:Ignorable="d"
d:DesignHeight="27" d:DesignWidth="300" Background="White">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ComboBox x:Name="cboJobStatus" Grid.Row="0" Grid.Column="0" Background="White"
DisplayMemberPath="Description"
SelectedValuePath="JobStatusRef"
SelectedValue="{Binding Path=JobStatus}" SelectionChanged="cboJobStatus_SelectionChanged" />
</Grid>
Additional:
This is what the background looks like after item is selected. I want the background to be white
You cannot do this due to a bug in the ControlTemplate for ComboBox.
Potential solution is to copy/edit the template and create your own.
This question is a duplicate. Perhaps the answer there can be updated with some more information. I searched for wpf cant change background of combobox and the top link is the MSDN answer on how to copy the template but even then the solution is riddled with issues with different Windows versions, aero theming, and does not address situations where users have high contrast turned on, and other accessibility issues.
I would recommend to use <ComboBox.ItemContainerStyle> and setup Background to Transparent for the container. Then each item background will be as in the ComboBox.

WPF Resize Window proportionally ie. No stretching or distorting?

I have a WPF Window which contains a Grid. It's set up to look like a Checkers board, so I need the squares of the grid to stay square when the window is resized.
I've tried many things but nothing seems to work. I hope it's just a matter of getting the right attribute, and not something complicated, but I need it to resize proportionally either way.
I'm also not sure if this should happen in the Grid or in the Window. I would assume the Window because that's the controller for resizing, but I could be wrong.
Any suggestions?
xaml for Window:
<Window x:Class="TicTacToeClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TicTacToeClient"
Title="Mini-Checkers V1.1" Height="600" Width="600"
MinHeight="200" MinWidth="200" MaxHeight="600" MaxWidth="600" >
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="Game">
<MenuItem Header="Set Ip Address" Name="IPAddressMenuItem"/>
<MenuItem Header="Set Name" Name="SetNameMenuItem"/>
</MenuItem>
</Menu>
<TextBlock DockPanel.Dock="Bottom" Text ="Status: " Name="GameStatusBar" />
<local:TicTacToeBoard x:Name="GameBoard" />
</DockPanel>
xaml for Grid:
<UserControl x:Class="TicTacToeClient.TicTacToeBoard"
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"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="600">
<Grid Name="MainGrid">
<Grid.RowDefinitions>
....
I would suggest DataBinding the Width of your Grid to the Height (or vice-versa). This will make sure that it always grows proportionally. Something as simple as this should work:
<Grid x:Name="Checkerboard" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="{Binding RelativeSource={RelativeSource Self}} Path=ActualHeight}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Grid Contents -->
</Grid>
And if you want your cells to all remain square, just make sure they're all * sized, so they will be spread out equally.
Alternatively, you can put yor grid inside a Viewbox with Stretch="Uniform"
You can try enclosing yourGameBoard in a ViewBox with Stretch Property set to Uniform and StretchDirection set to Both. like this. It wont keep the Form's Aspect ratio uniform but will keep your GameBoard Proportions Uniform.
<Viewbox Stretch="Uniform" StretchDirection="Both">
<local:TicTacToeBoard x:Name="GameBoard" />
</Viewbox>

Categories

Resources