So I have a main windows that loads a page this page is a settings page and I have the setting topmost, because I am using a page to display the buttons I did:
if(TopMostCheckBox.IsChecked == true)
{
MainWindow main = new MainWindow();
main.Topmost = true;
}
if(TopMostCheckBox.IsChecked == false)
{
MainWindow main = new MainWindow();
main.Topmost = false;
}
but for some reason when I load my program I check box doesn't check top most so how can I make my page toggle top most for my main window.
Answering your Question title:
how can I make a topmost checkbox WPF C#
As a Minimal, Reproducible Example the following would apparently work in the MainWindow code-behind of a newly created WPF project:
XAML:
<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:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<CheckBox Checked="CheckBox_CheckedChanged"
Unchecked="CheckBox_CheckedChanged"/>
</Grid>
</Window>
MainWindow.CS:
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void CheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
Topmost = ((CheckBox)sender).IsChecked == true;
}
}
}
You can do this within the xaml
<Window
.........
Topmost="{Binding ElementName=chkbox, Path=IsChecked}" >
<Grid>
<CheckBox x:Name="chkbox" Content="topmost ?" />
</Grid>
</Window>
You're creating a new instance of mainwindow rather than referencing the existing instance.
if (TopMostCheckBox.IsChecked == true)
{
var main = Application.Current.MainWindow as MainWindow;
main.Topmost = true;
}
The above assumes you've not given mainwindow a different name to the default.
You might find you have to set topmost false and then true to get it to respond.
Related
I have two xaml toggles in separate files that I want to update simultaneously (if one is switched on the other should be too (and vice versa). My first switch in xaml is:
<Switch Grid.Column="1" x:Name="toggleSwitch1" IsToggled="true" Toggled="OnToggled"/>
Using C# how can I return a boolean value of this switch so that I can update another switch simultaneously? Then once retrieving the value, how can I update the xaml of the toggle status for the other switch?
Your Switch control means, as I can understand, that you using UWP, but I'm not sure.
Anyway, the idea is to bind both controls IsToggled properties to same property of some ViewModel:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace MyWPFApp
{
public class ControlsViewModel : INotifyPropertyChanged
{
private bool switchToggled;
public bool SwitchToggled
{
get => switchToggled;
set
{
switchToggled = value;
OnPropertyChanged(nameof(SwitchToggled));
}
}
public ControlsViewModel() { }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then in XAML of both Windows set bindings to Switch control (in my example - CheckBox control):
<!-- Window 1 -->
<Window x:Class="MyWPFApp.Window1"
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:MyWPFApp"
mc:Ignorable="d"
Title="Window 1" Height="100" Width="300">
<Grid>
<CheckBox Content="Window1 CheckBox"
IsChecked="{Binding SwitchToggled}"/>
<!-- Replace IsChecked to IsToggled property -->
</Grid>
</Window>
<!-- Window 2 -->
<Window x:Class="MyWPFApp.Window2"
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:MyWPFApp"
mc:Ignorable="d"
Title="Window 2" Height="100" Width="300">
<Grid>
<CheckBox Content="Window2 CheckBox"
IsChecked="{Binding SwitchToggled}"/>
<!-- Replace IsChecked to IsToggled property -->
</Grid>
</Window>
Code-behind of both Windows in example is same:
using System.Windows;
namespace MyWPFApp
{
public partial class Window1 : Window // or public partial class Window2
{
public Window1(ControlsViewModel cvm) // or public Window2
{
InitializeComponent();
DataContext = cvm;
}
}
}
And when calling that example Windows to show from Main one, you creating ControlsViewModel instance and pass it to both:
using System.Windows;
namespace MyWPFApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var cvm = new ControlsViewModel();
new Window1(cvm).Show();
new Window2(cvm).Show();
}
}
}
So checking/unchecking (toggle/untoggle) one of them will affect another and vice versa. Also, you can change SwitchToggled from code somewhere, which would affect both controls too.
Please note, that this is just example to try explain the idea. More MVVM pattern explanations and examples you can find at MSDN.
I have a host window that has a page as follows:
<Window x:Class="myAPP.filesXAML.WinModel"
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:myApp.filesXAML"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
WindowStyle="None"
Title="myAPP" Height="562" Width="1000">
<Grid>
<Frame NavigationUIVisibility="Hidden" Source="/filesXAML/Login.xaml" Background ="White"/>
</Grid>
</Window>
Then in the code in C# I call another page as follows:
NavigationService.Navigate(new Uri("filesXAML/UserPage.xaml", UriKind.Relative));
At this point I want to change the size and style of the host window.
Is there a way to do it?
Any suggestions or comments are welcome.
You can use the following code to change the size of MainWindow in Page
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Application.Current.Windows[0].Width = 100;
Application.Current.Windows[0].Height = 100;
}
}
Instead of using a traditional splash screen, I want to display a login window to allow the user to enter their credentials. Meanwhile, in the background, I want to initialize the app, then load the main window. The problem is that the login window is covered up by the main window once shown.
private void App_OnStartup(object sender, StartupEventArgs e)
{
Current.MainWindow = new LoginWindow();
Current.MainWindow.Show();
Task.Run(() => { /*do app startup background stuff*/ }).ContinueWith(t =>
{
var appWindow = new ApplicationWindow();
appWindow.Show();
Current.MainWindow.Owner = appWindow;
}, TaskScheduler.FromCurrentSynchronizationContext());
The login window is made the main window from the start. My assumption was that by setting the ApplicationWindow's owner to the login window, the login window would remain on top. If I'm doing it wrong, is there a way to achieve what I want? The topmost flag works but then the window is, well, topmost, which is undesirable.
Suppose you have a MainWindow:
<Window x:Class="SO40189046.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:SO40189046"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Name="TimeText" />
</Grid>
</Window>
with code behind:
using System;
using System.Threading;
using System.Windows;
namespace SO40189046
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
// Background thread initializing the MainWindow
ThreadPool.QueueUserWorkItem((state) =>
{
for (int i = 0; i < 10; i++)
{
Dispatcher.Invoke(() =>
{
TimeText.Text = DateTime.Now.ToString();
});
Thread.Sleep(1000);
}
});
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
LoginWindow login = new LoginWindow();
login.Owner = App.Current.MainWindow;
login.WindowStartupLocation = WindowStartupLocation.CenterOwner;
if (!login.ShowDialog().GetValueOrDefault())
{
Close();
}
}
}
}
Then you can initialize your MainWindow while showing the login dialog.
AND you load the MainWindow as normal via StartUpUri in App.xaml
I have WPF window code and I want to change the window title, normally i can do
this.Title = "Bla"
But what if in xaml part of the window code, I have a text box named Title (Name="Title") which overrides the default window Title variable which sets the title of the window? How do I access the original window title variable without having to rename the textbox?
First solution.
You can use base keyword:
base.Title = "bla";
Second solution.
You can change window title in the Loaded event, by casting sender object to Window.
XAML:
<Window x:Class="WpfWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="title" Height="350" Width="525"
Loaded="Window_Loaded">
<Grid>
<TextBox Name="Title" MinWidth="100" />
</Grid>
</Window>
Code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
(sender as Window).Title = "bla";
}
}
I want to bind two controls like font size slider and text box, and each control is on different window on wpf, so how can I bind them?
Here's an example of how to do it:
1) Create a WPF project.
2) Change the contents of the MainWindow.xaml to the following (don't forget to correct the namespaces in all the code that I'm posting, for example in my code the namespace is WpfApplication2):
<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">
<StackPanel>
<Button Content="Settings Window" Click="SettingsWindowButton_OnClick"/>
<Button Content="Bound Window" Click="BoundWindowButton_OnClick"/>
</StackPanel>
</Window>
3) Change the contents of the MainWindow.xaml.cs to the following:
namespace WpfApplication2
{
using System.Windows;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
}
private void SettingsWindowButton_OnClick(object sender, RoutedEventArgs e)
{
var settingsWindow = new SettingsWindow();
settingsWindow.DataContext = viewModel;
settingsWindow.Show();
}
private void BoundWindowButton_OnClick(object sender, RoutedEventArgs e)
{
var boundWindow = new BoundWindow();
boundWindow.DataContext = viewModel;
boundWindow.Show();
}
}
}
4) Create a class named ViewModel in your project with the following code:
namespace WpfApplication2
{
using System.ComponentModel;
public class ViewModel : INotifyPropertyChanged
{
private int _fontSizeSetting = 10;
public event PropertyChangedEventHandler PropertyChanged;
public int FontSizeSetting
{
get { return _fontSizeSetting; }
set
{
_fontSizeSetting = value;
OnPropertyChanged("FontSizeSetting");
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
5) Add two new Windows to your project named BoundWindow and SettingsWindow with the following markup:
<Window x:Class="WpfApplication2.BoundWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BoundWindow" Height="300" Width="300">
<Grid>
<TextBox FontSize="{Binding FontSizeSetting, Mode=TwoWay}" Text="test..."/>
</Grid>
</Window>
-
<Window x:Class="WpfApplication2.SettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SettingsWindow" Height="300" Width="300">
<Grid>
<Slider Value="{Binding FontSizeSetting, Mode=TwoWay}" Minimum="10" Maximum="100"/>
</Grid>
</Window>
Now everything should be working as expected. What you basically did was to create a view model to set as the DataContext of your Windows. They both bind to the FontSizeSetting property of your view model, and when you change it in one window, WPF binding system takes care of changing the other value automatically.