Make Background Black Except for Single Control - c#

I have this:
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<StackPanel Orientation="Horizontal">
<StackPanel Width="100" Margin="20">
<CheckBox x:Name="cbFoo1" Content="Foo"/>
<TextBlock Text="Foo"/>
<TextBox />
</StackPanel>
<StackPanel Width="100" Margin="20">
<CheckBox x:Name="cbFoo2" Content="Foo"/>
<TextBlock Text="Foo"/>
<TextBox />
</StackPanel>
</StackPanel>
<Rectangle Fill="#BF000000" x:Name="rOverlay"/>
</Grid>
</Window>
I want to make a function foo with argument argControls() that makes rOverlay cover every control in the window except argControls(). Does anyone have any idea how to do this?

What about setting the visibility of the control to Collapsed when you want to hide them.

Option 1 - Draw Order
While a bit of a hack, perhaps the simplest way to accomplish this is to place controls that you wish covered before the rectangle and controls that you wish visible after the rectangle.
One step better (and not a hack) would to use the Panel.ZIndex property instead. This allows you to control the order that the UI elements are drawn regardless of the order that they are defined. This would be accomplished by setting the Panel.ZIndex as follows:
rOverlay to some arbitrary value (like 1)
controls to be covered to something lower than rOverlay (like 0)
controls to be visible to something higher than rOverlay (like 2)
It should however be noted that any transparent regions of your controls will still display the black rectangle behind them. This can either be specifying a background colour or by using another option presented here.
Option 2 - Clipping
Another more complex method involves setting the Clip property of the rectangle to a geometry that only includes the regions that you wish filled. This would likely be accomplished by using an instance of CombinedGeometry class with the CombineMode of Exclude. This would prevent the rectangle from drawing anything over regions outside the clipped region.

Related

How to efficiently scale all elements in a WinUI 3 desktop app when Window size changes?

I'd like to have everything in my WinUI 3 (v1.2) desktop app UI (MainWindow) scale up in size as the MainWindow changes in size. I'd also like to maintain the relative positioning of everything in the MainWindow. The purpose is to allow elderly users a quick and easy way to "enlarge" content by simply expanding the size of the window.
For example, take a vanilla Template Studio WinUI 3 desktop app with menu bar style navigation and a single page (call it MainPage). Replace MainPage.xaml with
<Page
x:Class="TestScale.Views.MainPage"
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"
mc:Ignorable="d">
<Grid Grid.Row="0" Grid.RowSpan="4">
<Border x:Name="Border" Width="300" Height="200" BorderThickness="2" BorderBrush="Red">
<TextBlock Text="The quick brown fox." HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Page>
which just draws a red rectangle with a TextBlock in the middle of the page (ignoring space used by ShellPage.xaml).
I'd like a straightforward way to scale everything, if possible, so that the rectangle and text increase in size (x and y) in the same proportions (dx and dy) that MainPage does when MainWindow changes, but also maintain their relative positions in the xy plane. I've tried using Scale and various Translations, but it always seems certain elements respond differently or only one dimension responds while the other stays fixed.
For example, adding
Scale="{x:Bind ((app:App)app:App.Current).ScaleToInitialSize, Mode=OneWay}"
to the definition of ShellPage.xaml almost does the trick except the position of the rectangle changes because the actual size of MainPage changes to reflect pixels used but the rectangle size reflects "scaled" sizes.
Is there a good discussion of scaling in WinUI 3 or UWP I've missed? I currently achieve this by binding everything to a Ratio property (Vector2 or Size) in my App class that changes whenever MainWindow.SizeChanged fires. Unfortunately, this means I also have to bind things like XAML Thickness, FontSize, and even CornerRadius properties to maintain the look and layout of the UI.
I expect this is a noob question but I can't seem to find any discussion anywhere. Any help gratefully appreciated.
You can use the ViewBox. The ViewBox scales its content automatically.
<Viewbox>
<Grid
Grid.Row="0"
Grid.RowSpan="4">
<Border
x:Name="Border"
Width="300"
Height="200"
BorderBrush="Red"
BorderThickness="2">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="The quick brown fox." />
</Border>
</Grid>
</Viewbox>

How to make use of the ViewBox control to make the application re-sizable?

ViewBox seems to be the go to tool if you want your application to be re-sizable, however, I still cannot get my head around on how to properly use it.
Here's my current code (this approach was recommended by a colleague)
<Window x:Class="WpfApp3.MainWindow"
WindowState="Maximized"
Width="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenWidthKey}}"
Height="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenHeightKey}}">
<Viewbox Stretch="UniformToFill">
<Grid Background="Peru"
Height="1080"
Width="15000">
<Grid Background="Bisque"
HorizontalAlignment="Left"
Width="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenWidthKey}}" >
</Grid>
</Grid>
</Viewbox>
</Window>
The approach is the following:
Wrap everything in a ViewBox with Stretch property set to UniformToFill, such that the aspect ratio of inner-elements in preserved
For the outer most grid, set the Width to some arbitrary huge number and Height to some arbitrary small number
We now have a huge rectangle going off screen to the right, while the height is the height of the window
Create a second grid and horizontally align it the the left
Put all other elements in this grid
Problems
The width of the second grid is set to the width of the primary screen, but because of the ViewBox and its stretch property the width if cut off, so I cannot really use it, as all the elements will be slightly-aligned to the left of the screen
Current layout
Questions
Is this the recommended way of creating dynamic / re-sizable applications in WPF?
Is this the correct way of using the ViewBox control?
How can I fix my problem?
Are there other solutions to using the ViewBox control?
I had this issue when I was trying to make a telerik grid re-sizable. Using a viewbox is the recommended way of creating re-sizable applications in WPF. I've found that using a dock panel is better than margins because it holds the control in place, while the viewbox controls the sizing. You can also add a grid with rows / columns if you need multiple controls. I'm very new to development, so this may not be best practice, however it works for our applications.
<Viewbox Stretch="Fill"
Grid.Row="1"
Grid.Column="1">
<DockPanel Height="300">
<Grid>
*User controls*
</Grid>
</DockPanel>
</Viewbox>

Setting opacity to the grid changes the opacity of the children controls with each other in windows 8

I have the Grid and I want to set the Opacity 50%. When I set the Opacity of the parent element, some children controls are seen under others. This occurs only in Metro application.
Please tell me how can I apply the Opacity similar to how it works in WPF.
I give a simplified example. In my case, the XAML is much complicated, so the color #80000000 for Grid is not a solution.
I use a multilayer user control. When I set Opacity to it, I see each layer, but layers inside the user control should not be transparent to each other.
<Grid Background="Black"
Opacity="0.5">
<Border Background="Red"
Opacity="1">
<TextBlock Text="Under"
FontSize="100" />
</Border>
<Border Background="Yellow"
Opacity="1">
<TextBlock Text="Over"
FontSize="100" />
</Border>
</Grid>
How it works in Metro: http://i.stack.imgur.com/EM9oJ.png
How it works in WPF (desired): http://i.stack.imgur.com/tRGxi.png
For example, when I set Opacity="0.5" for my book, the pages become also semitransparent: http: //i.stack.imgur.com/SvG0d.png
I think this is the bug in Metro.
Set CacheMode="BitmapCache" on your Grid. This behavior is no longer the default.
The likely reason is that the old behavior needed to render the semi-transparent element to a separate surface requiring more memory and two render passes, while the new default doesn't and should thus be faster, less hardware constrained and still work for many if not most cases.

wpf canvas won't resize

I am trying to learn WPF, but I have reached an impasse. The problem is that I have a control derived from UIControl, relevant parts:
<Grid>
<Border x:Name="OuterBorder" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="2" BorderBrush="Black">
<Canvas x:Name ="InternalCanvas" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Ivory">
</Canvas>
</Border>
</Grid>
This gives me a little black dot, when I render the control; I assume this is the border.
I then add code to the constructor after InitizializeComponents:
Label l = new Label();
l.Content = "HELLO";
l.BorderThickness = new Thickness(2);
l.BorderBrush = Brushes.Bisque;
if (this.GetType() == typeof(SO.SOGraphNode))
this.InternalCanvas.Children.Add(l);
The intent of the code is that if the class is not inherited, it should show some kind of placeholder. Which it does.
The problem is that InternalCanvas and it's ecplipsing OuterBorder won't resize around the newly created nice label.
The border remains a dot-border and InternalCanvas' Ivory background is not seen behind the label.
I have googled this alot, beliving that I needed to refresh or update the canvas/control elements, but I'm not so sure anymore. Mainly through watching a lot of Dispatcher.Invoke variations, which I have applied very liberally through out the code at different points, every time with no change in behavior.
WPF is a bit oblique to me still, if anyone knows how I could resolve this problem I do indeed have a shiny "Correct Answer" to dole out. :)
Edit 1 - Screenshot of the results:
Notice the general lack of Ivory background and OuterBorder still remains a small artifact in the topright corner of the control while the childelement is obviously much larger.
Is it important for you that the "InternalCanvas" element is type of canvas?
Because if you use for example a Grid instead, the sample works fine:
<Border x:Name="OuterBorder" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderThickness="2" BorderBrush="Black">
<Grid x:Name ="InternalGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Ivory">
</Grid>
</Border>
edit:
The reason for this behaviour you can read in the remarks section in MSDN:
Canvas is the only panel element that has no inherent layout characteristics. A Canvas has default Height and Width properties of zero, unless it is the child of an element that automatically sizes its child elements. Child elements of a Canvas are never resized, they are just positioned at their designated coordinates. This provides flexibility for situations in which inherent sizing constraints or alignment are not needed or wanted. For cases in which you want child content to be automatically resized and aligned, it is usually best to use a Grid element.
Can you show us how it rendered? I tried your xaml in a new project and I can't figure out what the problem is

C# WPF auto button spacing

I have a simple StackPanel on a grid and I want buttons within that stack panel to take up all space available (space between them should be the same).
In case it's not clear, there's a pic:
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" Orientation="Horizontal">
<Button MinWidth="115">OK</Button>
<Button MinWidth="115">Cancel</Button>
<Button MinWidth="115">Cancel</Button>
</StackPanel>
Is it possible or do I have to just enter margins manually?
Thanks!
Make your StackPanel into a Grid instead (you'll need to refactor what you currently have slightly), and evenly space out all of the columns (using a width of *), and then set each button's alignment to left/center/right respectively, which will achieve the layout you're looking for.

Categories