Can a single component of a page be full screen in winui3? - c#

This is a video stream playing module implemented by canvas. How to make the following CanvasControl display in full screen in winui 3?
<Grid>
<canvas:CanvasControl x:Name="canvas"></canvas:CanvasControl>
</Grid>

You create a full-screen window this way. You'll need to add your CanvasControl to both of them.
FullScreenWindow.xaml
<Window
x:Class="FullScreen.FullScreenWindow"
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:local="using:FullScreen"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel>
<Button
Click="CloseButton_Click"
Content="Close" />
</StackPanel>
</Window>
FullScreenWindow.xaml.cs
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using System;
namespace FullScreen;
public sealed partial class FullScreenWindow : Window
{
public FullScreenWindow()
{
this.InitializeComponent();
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
ThisAppWindow = AppWindow.GetFromWindowId(windowId);
ThisAppWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
}
public static AppWindow? ThisAppWindow;
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
MainWindow.xaml
<Window
x:Class="FullScreen.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"
mc:Ignorable="d">
<Grid>
<Button
Click="Button_Click"
Content="Launch full-screen window" />
</Grid>
</Window>
MainWindow.xaml.cs
using Microsoft.UI.Xaml;
namespace FullScreen;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private FullScreenWindow? fullScreenWindow;
private void Button_Click(object sender, RoutedEventArgs e)
{
fullScreenWindow = new();
fullScreenWindow.Activate();
}
}
BTW, we have MediaPlayer for playing videos.
UPDATE
This way you can pass a control to the other Window. This works with a TextBox so I guess it should work with your CanvasControl too.
FullScreenWindow.xaml
<Window
x:Class="FullScreen.FullScreenWindow"
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:local="using:FullScreen"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel>
<Button
Click="CloseButton_Click"
Content="Close" />
<Grid x:Name="InputBoxControlGrid" />
</StackPanel>
</Window>
FullScreenWindow.xaml.cs
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using System;
namespace FullScreen;
public sealed partial class FullScreenWindow : Window
{
public static AppWindow? ThisAppWindow;
public FullScreenWindow()
{
this.InitializeComponent();
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
ThisAppWindow = AppWindow.GetFromWindowId(windowId);
ThisAppWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
}
private UIElement? InputBoxControl { get; set; }
public void InstallInputBoxControl(UIElement inputBoxControl)
{
InputBoxControl = inputBoxControl;
this.InputBoxControlGrid.Children.Add(InputBoxControl);
}
public UIElement? UninstallInputBoxControl()
{
this.InputBoxControlGrid.Children.Remove(InputBoxControl);
UIElement? inputBoxControl = this.InputBoxControl;
this.InputBoxControl = null;
return inputBoxControl;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
MainWindow.xaml
<Window
x:Class="FullScreen.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:local="using:FullScreen"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel>
<Button
Click="Button_Click"
Content="Launch full-screen window" />
<ContentControl x:Name="InputBoxContainer">
<TextBox />
</ContentControl>
</StackPanel>
</Window>
MainWindow.xaml.cs
using Microsoft.UI.Xaml;
namespace FullScreen;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private FullScreenWindow? FullScreenWindow { get; set; }
public void InstallInputBoxControl(UIElement inputBoxControl)
{
this.InputBoxContainer.Content = inputBoxControl;
}
public UIElement? UninstallInputBoxControl()
{
UIElement? inputBoxControl = this.InputBoxContainer.Content as UIElement;
this.InputBoxContainer.Content = null;
return inputBoxControl;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
FullScreenWindow = new();
if (UninstallInputBoxControl() is UIElement content)
{
FullScreenWindow.InstallInputBoxControl(content);
}
FullScreenWindow.Closed += FullScreenWindow_Closed;
FullScreenWindow.Activate();
}
private void FullScreenWindow_Closed(object sender, WindowEventArgs args)
{
if (sender is FullScreenWindow fullScreenWindow)
{
if (fullScreenWindow.UninstallInputBoxControl() is UIElement inputBoxControl)
{
this.InputBoxContainer.Content = inputBoxControl;
}
}
}
}

Related

PointerPoint.Properties.MouseWheelDelta tilt or scroll

I have a function that listenes to PointerWheelChanged events of my UIElement.
I can retreive the MouseWheelDelta but this doesn't tell me if the mouse wheel was tilted or moved up/down.
How can I get this info?
This is my code to get the delta:
private void TestScrollViewer_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
PointerPoint ptrPt = e.GetCurrentPoint((UIElement)sender);
int delta = ptrPt.Properties.MouseWheelDelta;
// positive: forward/right motion; negative: backward/left motion
}
You can use IsHorizontalMouseWheel inside Pointers. See this example below:
MainWindow.xaml
<Window
x:Class="MouseWheelTests.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:local="using:MouseWheelTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid RowDefinitions="Auto,*">
<StackPanel Grid.Row="0">
<TextBlock x:Name="WheelHorizontal" />
<TextBlock x:Name="WheelVertical" />
</StackPanel>
<Grid
Grid.Row="1"
Background="Transparent"
PointerWheelChanged="Grid_PointerWheelChanged" />
</Grid>
</Window>
MainWindow.xaml.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Input;
namespace MouseWheelTests;
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private int WheelHorizontalValue { get; set; }
private int WheelVerticalValue { get; set; }
private void Grid_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
var properties = e.GetCurrentPoint((UIElement)sender).Properties;
if (properties.IsHorizontalMouseWheel is true)
{
WheelHorizontalValue += properties.MouseWheelDelta;
this.WheelHorizontal.Text = $"Horizontal: {WheelHorizontalValue}";
}
else
{
WheelVerticalValue += properties.MouseWheelDelta;
this.WheelVertical.Text = $"Vertical: {WheelVerticalValue}";
}
}
}

WPF MVVM Key Binding

I'm new to WPF, and the code I've written doesn't seem to be working. I'm trying to move a rectangular paddle to the left when the left arrow key is pressed, but I get no response when I press the Left arrow key. What am I doing wrong here?
Here is the View:
<UserControl.InputBindings>
<KeyBinding Key="Left" Command="{Binding MovePaddleLeftCommand}"/>
</UserControl.InputBindings>
and here is the code in the ViewModel:
private ICommand _movePaddleLeftCommand;
public ICommand MovePaddleLeftCommand
{
get
{
return new DelegateCommand(ExecuteCommand, CanExecute);
}
}
private void ExecuteCommand()
{
MessageBox.Show("Left");
MovePaddleLeft();
}
private bool CanExecute()
{
return true;
}
Below is a more complete picture of the code in case it's relevant.
GameView.xaml:
<UserControl x:Class="Arkanoid_MkII.Views.GameView"
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:Arkanoid_MkII.Views"
mc:Ignorable="d"
Width="1500" Height="800">
<Canvas Name="GameArea" ClipToBounds="True">
<Rectangle Canvas.Left="{Binding Path=Paddle.PaddleX}" Canvas.Top="750" Width="{Binding Path=Paddle.Width}" Height="{Binding Path=Paddle.Height}" Fill="{Binding Path=Paddle.Colour}"/>
</Canvas>
<UserControl.InputBindings>
<KeyBinding Key="Left" Command="{Binding MovePaddleLeftCommand}"/>
</UserControl.InputBindings>
</UserControl>
GameView.xaml.cs:
public partial class GameView : UserControl
{
public GameView()
{
InitializeComponent();
}
}
MainWindow.xaml:
<Window x:Class="Arkanoid_MkII.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:Arkanoid_MkII"
xmlns:views="clr-namespace:Arkanoid_MkII.Views"
mc:Ignorable="d"
Title="MainWindow" SizeToContent="WidthAndHeight" ResizeMode="NoResize" Background="Black" Padding="100">
<Grid>
<Border BorderBrush="Black" BorderThickness="5">
<views:GameView x:Name="GameViewControl" Loaded="GameViewControl_Loaded" />
</Border>
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void GameViewControl_Loaded(object sender, RoutedEventArgs e)
{
Arkanoid_MkII.ViewModels.GameViewModel gameViewModelObject = new Arkanoid_MkII.ViewModels.GameViewModel();
GameViewControl.DataContext = gameViewModelObject;
}
}
GameViewModel.cs:
private ICommand _movePaddleLeftCommand;
public ICommand MovePaddleLeftCommand
{
get
{
return new DelegateCommand(ExecuteCommand, CanExecute);
}
}
private void ExecuteCommand()
{
MessageBox.Show("Left");
MovePaddleLeft();
}
private bool CanExecute()
{
return true;
}
The UserControl must be focusable and focused for the command to be executed:
private void GameViewControl_Loaded(object sender, RoutedEventArgs e)
{
Arkanoid_MkII.ViewModels.GameViewModel gameViewModelObject =
new Arkanoid_MkII.ViewModels.GameViewModel();
GameViewControl.DataContext = gameViewModelObject;
GameViewControl.Focusable = true;
Keyboard.Focus(GameViewControl);
}

One way dependency property changed notification

I'm trying to make a user control with a dependency property. I need to execute certain logic when the dependency property is changed from outside the usercontrol, but that logic shouldn't execute when the dependency property is changed from inside the user control. I have this small sample. I only want to execute certain logic when the value is set from mainwindow and not when it is set by clicking the checkbox. I don't know if PropertyChangedCallbackis the correct way, but this is what I have.
UserControl:
public partial class UserControl1 : UserControl
{
public int MyProperty
{
get { return (int)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(int), typeof(UserControl1), new PropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Only process the 5, don't process the 6
}
public UserControl1()
{
InitializeComponent();
}
private void checkBox_Click(object sender, RoutedEventArgs e)
{
MyProperty = 6;
}
}
UserControl xaml:
<UserControl x:Class="WpfApplication4.UserControl1"
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="300" d:DesignWidth="300">
<Grid>
<CheckBox x:Name="checkBox" Click="checkBox_Click"/>
</Grid>
</UserControl>
MainWindow:
public partial class MainWindow : Window
{
public int MainWindowProperty { get; set; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MainWindowProperty = 5;
}
}
Mainwindow xaml:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 MyProperty="{Binding MainWindowProperty}"/>
</Grid>
</Window>
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!disableProcessing)
{
// Only process the 5, don't process the 6
}
}
bool disableProcessing = false;
private void checkBox_Click(object sender, RoutedEventArgs e)
{
disableProcessing = true;
MyProperty = 6;
disableProcessing = false;
}

My property does not update using [CallerMemberName]

Admittedly I am new to wpf. But i have spent some time Googling about it all and I am stumped.
in essence i want to update my TextBlock in my UI using Binding whenever my Model values change.
So this is my Model:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApplication1
{
public class MyModel : INotifyPropertyChanged
{
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
public string MyField { get; set ; }
}
}
This is my UI:
<Window x:Class="WpfApplication1.MainWindow"
xmlns:viewModels="clr-namespace:WpfApplication1"
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:WpfApplication1"
d:DataContext="{d:DesignInstance viewModels:MyModel, IsDesignTimeCreatable=True}"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<viewModels:MyModel></viewModels:MyModel>
</Window.DataContext>
<Grid>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding MyModel.MyField}"></TextBlock>
<Button Content="Click Me!" Click="Button_Click" />
</StackPanel>
</Grid>
</Window>
This is my code behind:
using System.Windows;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public MyModel myModel = new MyModel();
private void Button_Click(object sender, RoutedEventArgs e)
{
myModel.MyField = "has worked";
}
}
}
When i press the button the text does not change on the UI..?
The instance you create in the code behind is not the same as you assign in xaml.
Change the button click event to
private void Button_Click(object sender, RoutedEventArgs e)
{
var model = this.DataContext as MyModel;
model.MyField = "has worked";
}
And the binding in xaml to
<TextBlock Text="{Binding MyField}"></TextBlock>
And in your viewmodel you are not calling the notify property changed. So create a private field and modify the property as below.
private string myField;
public string MyField
{
get { return this.myField; }
set { this.SetProperty(ref this.myField, value); }
}

checkbox checked or click event not firing in datatemplate

I have a checkbox in my datatemplate and for some reason the events are not firing. see code below. my datatemplate is in a resource dictionary with code behind file. Any Ideas?
<ResourceDictionary x:Class="ArmyBuilder.Templates.EquipmentDataTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<DataTemplate x:Key="EquipmentDataTemplate">
<Grid>
<CheckBox Content="{Binding Name}" Checked="ToggleButton_OnChecked" Click="CheckBox_Click"/>
</Grid>
</DataTemplate>
//code behind
namespace ArmyBuilder.Templates
{
public partial class EquipmentDataTemplate : ResourceDictionary
{
public EquipmentDataTemplate()
{
InitializeComponent();
}
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
// breakpoint not hit
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
// breakpoint not hit
}
}
}
I am not sure how you use it, but the your code works for me and the click event got fired. Check the following and if you still cannot find the point, share a repro project to show how you used it.
Template XAML:
<ResourceDictionary x:Class="App10.EquipmentDataTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<DataTemplate x:Key="EquipmentDataTemplate">
<Grid>
<CheckBox Content="Click Me" Checked="ToggleButton_OnChecked" Click="CheckBox_Click"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
Template cs:
namespace App10
{
public sealed partial class EquipmentDataTemplate : ResourceDictionary
{
public EquipmentDataTemplate()
{
this.InitializeComponent();
}
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
// breakpoint not hit
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
// breakpoint not hit
}
}
}
In MainPage.Xaml, use the template in a ListView:
<Page
x:Class="App10.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App10"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<local:EquipmentDataTemplate></local:EquipmentDataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="listView" CanReorderItems="True" AllowDrop="True" ItemTemplate="{StaticResource EquipmentDataTemplate}">
</ListView>
</Grid>
</Page>
In MainPage cs:
namespace App10
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var list = new ObservableCollection<string>();
for (int i = 0; i < 10; i++)
{
list.Add("Item " + i);
}
listView.ItemsSource = list;
}
}
}

Categories

Resources