When i went to add an event to the button which i dragged and dropped from toolbox to the window, the event handler on the properties window was not visible.. because of this reason, i added the event manually (by typing). but after when i built it and pressed F5, the button was not firing the event.
here is a little example that must be work ;-)
<Window x:Class="WpfStackOverflowSpielWiese.Window8"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window8"
Height="300"
Width="300">
<Grid>
<Button Click="Button_Click" />
</Grid>
</Window>
code behind
using System.Windows;
namespace WpfStackOverflowSpielWiese
{
/// <summary>
/// Interaction logic for Window8.xaml
/// </summary>
public partial class Window8 : Window
{
public Window8() {
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
// do something....
}
}
}
hope that helps you...
Related
I've been working with Live Visual Tree and Live Property Explorer in Visual Studio 2022 Enterprise for a while now to help debug WinUI 3 UIs. Strangely, I just noticed that the Live Property Explorer doesn't display any inherited properties for derived or wrapped WinUI 3 controls.
For example, here is some code for a small extension to the Button control. All the extension does is expose the Button's current CommonStates VisualState via a ButtonVisualState dependency property and a ButtonVisualStateChanged event.
SuperButton.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace SuperButtonTest.Controls;
/// <summary>
/// A Button that exposes its visual state via ButtonVisualState
/// </summary>
public class SuperButton : Button
{
public event EventHandler? ButtonVisualStateChanged;
protected virtual void OnButtonVisualStateChanged(EventArgs e) => ButtonVisualStateChanged?.Invoke(this, e);
#region ButtonVisualState
public static readonly DependencyProperty ButtonVisualStateProperty = DependencyProperty.Register(
nameof(ButtonVisualState), typeof(VisualState), typeof(SuperButton), new PropertyMetadata(null));
public VisualState ButtonVisualState
{
get => (VisualState)GetValue(ButtonVisualStateProperty);
set => SetValue(ButtonVisualStateProperty, value);
}
#endregion
public SuperButton()
{
DefaultStyleKey = typeof(Button);
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var vsg = GetTemplateChild("CommonStates") as VisualStateGroup ??
throw new ArgumentNullException("CommonStates VisualStateGroup not found in SuperButton");
ButtonVisualState = vsg.CurrentState;
vsg.CurrentStateChanged += OnCurrentStateChanged;
}
private void OnCurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
if (e.Control is SuperButton)
{
ButtonVisualState = e.NewState;
OnButtonVisualStateChanged(EventArgs.Empty);
}
}
}
This XAML then shows a regular Button control and a SuperButton:
MainPage.xaml
<Page
x:Class="SuperButtonTest.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"
xmlns:ctrl="using:SuperButtonTest.Controls"
mc:Ignorable="d">
<Grid x:Name="ContentArea">
<StackPanel Orientation="Vertical">
<Button x:Name="NormalButton" Content="Normal Button"/>
<ctrl:SuperButton x:Name="SuperButton" Content="Super Button"/>
<TextBlock Text="{x:Bind SuperButton.ButtonVisualState.Name, Mode=OneWay}"/>
</StackPanel>
</Grid>
</Page>
If you open the Live Property Explorer when MainPage is displayed, examining the NormalButton shows all the expected Button properties and their values. If you examine the SuperButton instead, the Live Property Explorer displays... nothing (please see below). All of the inherited properties from Button are exposed to code and XAML, they're just not visible in the explorer.
Shouldn't they be? Is there a setting I've missed (Show Just My XAML is off)?
Exploring NormalButton
Exploring SuperButton
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.
I'm learning Microsoft.Expression.Interactions.WPF. I'm attempting to attach a behavior to a grid's MouseDown event. The OnAttached method gets called, but my behavior never receives the MouseDown event.
XAML
<Window x:Class="SequenceDiagramViewer.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:SequenceDiagramViewer"
xmlns:ineractivity="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
Title="Sequence Diagram Viewer" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<ineractivity:Interaction.Behaviors>
<local:MouseClick />
</ineractivity:Interaction.Behaviors>
</Grid>
</Window>
C#
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
namespace SequenceDiagramViewer
{
public class MouseClick : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
Console.WriteLine("OnAttached called");
AssociatedObject.MouseDown += AssociatedObject_MouseDown;
}
private void AssociatedObject_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("MouseDown called");
}
protected override void OnDetaching()
{
Console.WriteLine("OnDetaching called");
AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
}
}
}
In my console output, I only get OnAttached called. In addition, when I put a breakpoint in AssociatedObject_MouseDown, it never gets hit, but OnAttached does. How do I get the event to go to my behavior?
My grid background was transparent. As soon as I changed my grid XAML to this:
<Grid Background="White">
<interactions:Interaction.Behaviors>
<local:MouseClick />
</interactions:Interaction.Behaviors>
</Grid>
I then started getting mouse down events.
I have created a UserControl that has a command (DeleteCommand) inside:
public partial class TestControl : UserControl
{
public static RoutedCommand DeleteCommand = new RoutedCommand();
private void DeleteCommandExecute(object sender, ExecutedRoutedEventArgs e)
{
}
private void DeleteCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public TestControl()
{
InitializeComponent();
CommandBinding deleteCommandBinding = new CommandBinding(DeleteCommand, DeleteCommandExecute, DeleteCommandCanExecute);
this.CommandBindings.Add(deleteCommandBinding);
}
}
I have put this UserControl inside a Window:
<Window x:Class="TestRoutedCommand.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestRoutedCommand"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Fire event" Margin="156,29,205,254" Command="{x:Static local:TestControl.DeleteCommand}" />
<local:TestControl Margin="126,135,135,46"/>
</Grid>
</Window>
There is also a Button which is using the DeleteCommand. My problem is that this button is always disabled and the DeleteCommandCanExecute handler is never called, although e.CanExecute is always set to true.
I have tried to call:
CommandManager.InvalidateRequerySuggested();
but nothing happens. The event is never fired. Maybe I am doing the CommandBinding wrong.
What I want to achieve is that when the user clicks on the button that the DeleteCommandExecute handler is fired. My goal is to create commands for my MenuButtons which will trigger some methods in my UserControls which can be deep in the Visual Tree.
Slightly change your XAML:
<Grid>
<Button Content="Fire event" Margin="156,29,205,254" Command="{x:Static local:TestControl.DeleteCommand}" CommandTarget="{Binding ElementName=Control1}" />
<local:TestControl x:Name="Control1" Margin="126,135,135,46"/>
</Grid>
CommandTarget says where to find needed handlers.
I want to open the help file to a page based on some custom logic. How can I handle the user pressing F1 on all of my windows (main window and modal dialogs) ?
I know how to handle F1 in a single window, but can this be done globally, so I don't have to add the same code to all of my windows ?
Below is the test with which I've tried out that F1 does not work on the child window.
Window1.xaml:
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Help"
Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<Grid>
<Button Content="Open a new window"
Click="Button_Click"/>
</Grid>
</Window>
Window1.xaml.cs:
using System.Windows;
using System.Windows.Input;
namespace WpfApplication2
{
partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Help");
}
void Button_Click(object sender, RoutedEventArgs e)
{
new Window().ShowDialog();
}
}
}
I've found the answer on this page.
That is, put this in the main window's constructor for example:
CommandManager.RegisterClassCommandBinding(typeof(Window),
new CommandBinding(ApplicationCommands.Help,
(x, y) => MessageBox.Show("Help")));