wpf Frame.Navigate can't push stack when calls two times - c#

Page1 page1 = new Page1();
Page2 page2 = new Page2();
Page3 page3 = new Page3();
private void btnNextClick(object sender, RoutedEventArgs e)
{
navi.Navigate(page1);
navi.Navigate(page2);
}
As shown in the code above, I want the Frame first to navigate to "page1",and then to navigate to "page2".
As a result,it did navigate to "page2",but I have't see "page1" in Fram.BackStack. So I can't navigate back. And I found Frame.Navigating event trigged twice, and Frame.Navigated trigged once. It seems the first navigate was canceled, and I want know why?
And, Is there another way to achieve this effect?(navigate to page1 and quickly navigate to page2--->then navigate back to page1)
Additional information:
my full c# code:
public partial class MainWindow : Window
{
Page1 page1 = new Page1();
Page2 page2 = new Page2();
Page3 page3 = new Page3();
public MainWindow()
{
InitializeComponent();
navi.Navigated += Navi_Navigated;
navi.Navigating += Navi_Navigating;
}
private void Navi_Navigating(object sender, NavigatingCancelEventArgs e)
{
}
private void Navi_Navigated(object sender, NavigationEventArgs e)
{
}
private void btnPreviousPageClick(object sender, RoutedEventArgs e)
{
if (navi.CanGoBack)
{
navi.GoBack();
}
}
private void btnNextClick(object sender, RoutedEventArgs e)
{
navi.Navigate(page1);
navi.Navigate(page2);
}
private void btnNextClick2(object sender, RoutedEventArgs e)
{
navi.Navigate(page2);
}
private void btnNextClick3(object sender, RoutedEventArgs e)
{
navi.Navigate(page3);
}
}
and my xaml code:
<Window x:Class="mmNavigate.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:mmNavigate"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Frame JournalOwnership="OwnsJournal" NavigationUIVisibility="Visible" x:Name="navi" Height="280"></Frame>
<StackPanel Orientation="Horizontal">
<Button Content="Previous" Click="btnPreviousPageClick"/>
<Button Content="Page1" Margin="20,0,0,0" Click="btnNextClick"/>
<Button Content="Page2" Margin="20,0,0,0" Click="btnNextClick2"/>
<Button Content="Page3" Margin="20,0,0,0" Click="btnNextClick3"/>
</StackPanel>
</StackPanel>

You should wait to navigate to Page2 until the navigation to Page1 has been completed by handling the Navigated event:
private void btnNextClick(object sender, RoutedEventArgs e)
{
navi.Navigated += Navi_Navigated1; ;
navi.Navigate(page1);
}
private void Navi_Navigated1(object sender, NavigationEventArgs e)
{
navi.Navigated -= Navi_Navigated1;
navi.Navigate(page2);
}

Related

the event that was called from window1 to window 2 in WPF Not working

**
I have 2 windows in app. mainwindow with 2 buttons and window1 with a
label. btn one opens window1 and btn 2 changes window1 label color.
**
public partial class MainWindow : Window
{
Window1 sWindow = new Window1();public MainWindow()
{InitializeComponent();
}
private void btnFirstWindow_Click(object sender, RoutedEventArgs e)
{
sWindow.Show();
}
private void btnChangeBackground_Click_1(object sender, RoutedEventArgs e)
{
sWindow.ChangeBackground();
}
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
public void ChangeBackground()
{
if (lblShowUser.Background == Brushes.Green)
{
lblShowUser.Background = new LinearGradientBrush(Colors.Red, Colors.Red, 90);
}
else
{
lblShowUser.Background = Brushes.Green;
}
}
}
IF I remove this part
**
private void btnFirstWindow_Click(object sender, RoutedEventArgs e)
{
sWindow.Show();
}
** From mainwindow and add both windows at app xaml
Startup="App_Startup"
StartupUri="MainWindow.xaml">
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
Window1 sWindow = new Window1();
sWindow.Show();
}
}
the method of label changing color when i press the other button doesnt work
am new to C# and wpf So when answering please also give explantion on what to be done to the code and why
expecting it to work even if changes are made regarding when the other page shows up but its not working
Create an object as a field from Window1 class, then you can access its objects.
Output (tested in Visual Studio 2017, .Net Framework 4.5.2):
Note: if this solution helps you, please mark as answer (don't forget to vote for me).
XAML (Mainwindow):
<Window x:Class="WpfApp.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:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="OpenButton" Click="OpenButton_Click" Content="Open" HorizontalAlignment="Left" VerticalAlignment="Center" Width="75" Margin="99,0,0,0"/>
<Button x:Name="ChangeColorButton" Click="ChangeColorButton_Click" Content="Changing color" HorizontalAlignment="Left" VerticalAlignment="Center" Width="99" Margin="331,0,0,0"/>
</Grid>
</Window>
XAML (Window1):
<Window x:Class="WpfApp.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:WpfApp"
mc:Ignorable="d"
Title="Window1" Closing="Window_Closing" Height="300" Width="300">
<Grid>
<Label x:Name="Label" Content="Label" HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto"/>
</Grid>
</Window>
C# (MainWindow):
public partial class MainWindow : Window
{
Window1 W1 = new Window1();
public MainWindow()
{
InitializeComponent();
}
private void OpenButton_Click(object sender, RoutedEventArgs e)
{
W1.ShowDialog();
}
private void ChangeColorButton_Click(object sender, RoutedEventArgs e)
{
W1.Label.Background = new SolidColorBrush(Colors.Blue);
}
}
C# (Window1):
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.Visibility = Visibility.Hidden;
}
}
Thanks

WPF Textbox does not allows input when it is displayed in context menu on system tray

I want to provide search functionality on context menu displayed in the system tray. I am using System.Windows.Forms.NotifyIcon class to display the context menu in the tray. Basically this search should allow the user to find the required menu from the context menu. For that, I added the WPF textbox like this in the below image, but it does not allow me to type the text.
Is there any way to handle the text input on this?
Here is my code,
MainWindow.xaml
<Window x:Class="SysTray_Sample.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:SysTray_Sample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ContextMenu x:Key="NotifierContextMenu"
Placement="MousePoint">
<MenuItem Header="First" StaysOpenOnClick="True"/>
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<TextBox Text="Test" Width="120" />
</MenuItem.Header>
</MenuItem>
<MenuItem Header="Open" Click="Menu_Open"/>
<MenuItem Header="Close" Click="Menu_Close"/>
</ContextMenu>
</Window.Resources>
<Grid>
<Button Height="22" Width="180" Content="Right click over me">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Click="MenuItem_Click" Header="Minimize to system tray"/>
<MenuItem Header="Desktop mode"/>
<TextBox Width="150"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private System.Windows.Forms.NotifyIcon _trayIcon;
public MainWindow()
{
InitializeComponent();
_trayIcon = new System.Windows.Forms.NotifyIcon();
_trayIcon.MouseDown += MyNotifyIcon_MouseDown;
_trayIcon.Icon = new System.Drawing.Icon(#"Resources\add.ico");
_trayIcon.MouseDoubleClick += MyNotifyIcon_MouseDoubleClick;
}
private void MyNotifyIcon_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenu menu = (ContextMenu)this.FindResource("NotifierContextMenu");
menu.IsOpen = true;
}
}
private void MyNotifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
this.WindowState = WindowState.Normal;
_trayIcon.Visible = false;
this.ShowInTaskbar = true;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
this.ShowInTaskbar = false;
_trayIcon.BalloonTipTitle = "Minimize Sucessful";
_trayIcon.BalloonTipText = "Minimized the app ";
_trayIcon.ShowBalloonTip(400);
_trayIcon.Visible = true;
this.WindowState = WindowState.Minimized;
}
private void Menu_Open(object sender, RoutedEventArgs e)
{
MessageBox.Show("Open");
}
private void Menu_Close(object sender, RoutedEventArgs e)
{
MessageBox.Show("Close");
}
}
After a long hour of searching, I found the following solution which worked for my case.
https://www.codeproject.com/Questions/184429/Text-box-is-not-working-in-WPF-Popup
[DllImport("USER32.DLL")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ActivateVisual(FrameworkElement contextMenu)
{
var fromVisual = HwndSource.FromDependencyObject(contextMenu);
HwndSource source = (HwndSource)fromVisual;
IntPtr handle = source.Handle;
SetForegroundWindow(handle);
}
Here is my complete MainWindow.xaml.cs code,
public partial class MainWindow : Window
{
private System.Windows.Forms.NotifyIcon _trayIcon;
[DllImport("USER32.DLL")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ActivateVisual(FrameworkElement contextMenu)
{
var fromVisual = HwndSource.FromDependencyObject(contextMenu);
HwndSource source = (HwndSource)fromVisual;
IntPtr handle = source.Handle;
SetForegroundWindow(handle);
}
public MainWindow()
{
InitializeComponent();
_trayIcon = new System.Windows.Forms.NotifyIcon();
_trayIcon.MouseDown += MyNotifyIcon_MouseDown;
_trayIcon.Icon = new System.Drawing.Icon(#"C:\Users\nambi\source\repos\SysTray_Sample\SysTray_Sample\Resources\add.ico");
_trayIcon.MouseDoubleClick += MyNotifyIcon_MouseDoubleClick;
}
private void MyNotifyIcon_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
ContextMenu menu = (ContextMenu)this.FindResource("NotifierContextMenu");
menu.IsOpen = true;
ActivateVisual(this.ContextMenu);
}
}
private void MyNotifyIcon_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
this.WindowState = WindowState.Normal;
_trayIcon.Visible = false;
this.ShowInTaskbar = true;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
this.ShowInTaskbar = false;
_trayIcon.BalloonTipTitle = "Minimize Sucessful";
_trayIcon.BalloonTipText = "Minimized the app ";
_trayIcon.ShowBalloonTip(400);
_trayIcon.Visible = true;
this.WindowState = WindowState.Minimized;
}
private void Menu_Open(object sender, RoutedEventArgs e)
{
ActivateVisual(this);
MessageBox.Show("Open");
}
private void Menu_Close(object sender, RoutedEventArgs e)
{
ActivateVisual(this);
MessageBox.Show("Close");
}
}

Routing class for navigation between forms

I'm new to C# and object orientated coding therefore I was wondering how to create a routing class for navigation between forms in a .Net Framework WPF application.
At the moment I am navigating between forms like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
new Classes.SessionService();
}
private void Customer_Page_click(object sender, RoutedEventArgs e)
{
CustomerPage CP = new CustomerPage();
CP.Show();
this.Close();
}
private void Staff_Menu_click(object sender, RoutedEventArgs e)
{
Forms.StaffPage SP = new Forms.StaffPage();
SP.Show();
this.Close();
}
private void Exit_click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
I have been told it is better to create a routing class as it will separate code more, but I have not been able to find an example for navigating between forms but only between web pages.
Im strongly recommend you to use an existing library bevor starting to create your own infrastructure. (I've learnd it the hard way and ended up using prism ;) ) There are other great libraries out there, too. Just go to youtube and search for "c# prism outlook" there is a pretty good prism tutorial from brian lagunas.
Edit:
Just to give you an basic idea how you can solve this by yourself:
Main Window xaml:
<Window x:Class="WpfTestApp.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:WpfTestApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<WrapPanel Grid.Row="0" x:Name="Ribbon"/>
<ContentPresenter Grid.Row="1" x:Name="Content"/>
<StackPanel Grid.Row="2">
<Button Grid.Row="0" Content="SetContentFormA" Click="Button_Click"/>
<Button Grid.Row="0" Content="SetContentFormB" Click="Button_Click_1"/>
<Button Grid.Row="0" Content="AddNewFormAToRibbon" Click="Button_Click_2"/>
<Button Grid.Row="0" Content="RemoveFormBFromRibbon" Click="Button_Click_3"/>
</StackPanel>
</Grid>
MainWindow.cs:
public partial class MainWindow : Window
{
private FormB b;
public MainWindow()
{
InitializeComponent();
PageControler.Content = Content;
PageControler.Ribbon = Ribbon;
b = new FormB();
Ribbon.Children.Add(b);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
PageControler.SetContent(new FormA());
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
PageControler.SetContent(new FormB());
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
PageControler.AddToRibbon(new FormA());
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
PageControler.RemoveFromRibbon(b);
}
}
PageControler:
public static class PageControler
{
public static ContentPresenter Content { get; set; }
public static WrapPanel Ribbon { get; set; }
public static void SetContent(UserControl control)
{
Content.Content = control;
}
public static void AddToRibbon(UserControl control)
{
Ribbon.Children.Add(control);
}
public static void RemoveFromRibbon(UserControl control)
{
Ribbon.Children.Remove(control);
}
}
FormA (& B):
<UserControl x:Class="WpfTestApp.FormA"
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:WpfTestApp"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="Violet">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="Form A"/>
</Grid>
You can althou

In spite of setting IsDeleteble Property as "IsDeletable = true" I Can't delete chip

In spite of setting IsDeletable property as IsDeletable=True,
I kept clicking the chip delete icon but nothing happened.
How Can I delete chip clicking delete icon?
mainwindow.xaml
<StackPanel Orientation="Horizontal" x:Name="addchip">
<Button Click="create_chip">delete_chip</Button>
<materialDesign:Chip
Content="Example Chip"
ToolTip="This is an example chip" IsDeletable="True"/>
</StackPanel>
mainwindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void deletenotify(object sender, RoutedEventArgs e)
{
Debug.WriteLine("delete!");
}
private void create_chip(object sender, RoutedEventArgs e)
{
Chip a = new Chip();
a.Content = "Example Chip";
a.IsDeletable =true ;
a.DeleteClick += deletenotify;
addchip.Children.Add(a);
}
}
Try this:
Output:
Xaml:
<Window x:Class="TestChipDeleting.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"
Title="MainWindow"
Height="400"
Width="300"
Loaded="MainWindow_OnLoaded">
<Grid>
<ItemsControl Name="UsersListBox">
</ItemsControl>
</Grid>
</Window>
C#:
using System.Windows;
using MaterialDesignThemes.Wpf;
namespace TestChipDeleting
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
BindUsers();
}
private void Chip_OnDeleteClick(object sender, RoutedEventArgs e)
{
var currentChip = (Chip) sender;
UsersListBox.Items.Remove(currentChip);
}
private void BindUsers()
{
for (var i = 0; i < 10; i++)
{
var chip = new Chip {IsDeletable = true};
chip.DeleteClick += Chip_OnDeleteClick;
chip.Content = "Username" + i;
chip.Icon = i;
UsersListBox.Items.Add(chip);
}
}
}
}

wpf Usercontrol in usercontrol no response

I have a strange problem in my project. There are pages made from usercontrol and menu bar (also usercontrol).
Here is my usercontrol that contains few buttons
public partial class UpperBar : UserControl
{
public UpperBar()
{
InitializeComponent();
}
public event EventHandler EventbtClicked;
private void btConnect_Click(object sender, System.Windows.RoutedEventArgs e)
{
EventbtClicked(this, e);
}
}
I added this in my page as follows:
<local:UpperBar VerticalAlignment="Top" Grid.Row="0" Height="78" Grid.ColumnSpan="3" Margin="0,2,0,0"/>
And in my page tried to call event:
public PageStatus()
{
InitializeComponent();
Plc.ExecuteRefresh += new EventHandler(RefreshLeds);
UpperBar.EventbtCliced += new EventHandler(UpperBatButtonClick);
}
protected void UpperBarButtonClick(object sender, EventArgs e)
{
//do something
}
But I can't access my event using this UpperBar.EventbtCliced, why ?
You need to access the instance of your class UpperBar in PageStatus, not the class UpperBar itself!
The easiest way for you here:
Name your UpperBar in your XAML, example:
<local:UpperBar x:Name="_myBar" x:FieldModifier="private"/>
Then use this instance in your PageStatus.xaml.cs:
public partial class MainWindow : Window {
public MainWindow()
{
InitializeComponent();
_myBar.EventbtClicked += new EventHandler(UpperBarButtonClick);
}
protected void UpperBarButtonClick(object sender, EventArgs e)
{
//do something
}
}
Now if you are working seriously in WPF, you should really learn about Databinding and MVVM, catching event this way is not the best way to do it at all.
You should use Custom Command (RoutedUICommand) rather than bubbling event from user control.
here are some steps to follow in contrast to your approach:
1: create class myCustomCommand.
namespace WpfApplication1
{
public class myCustomCommand.
{
private static RoutedUICommand _luanchcommand;//mvvm
static myCustomCommand.()
{
System.Windows.MessageBox.Show("from contructor"); // static consructor is called when static memeber is first accessed(non intanciated object)
InputGestureCollection gesturecollection = new InputGestureCollection();
gesturecollection.Add(new KeyGesture(Key.L,ModifierKeys.Control));//ctrl+L
_luanchcommand =new RoutedUICommand("Launch","Launch",typeof(myCustomCommand.),gesturecollection);
}
public static RoutedUICommand Launch
{
get
{
return _luanchcommand;
}
}
}
}
In the xaml of UserControl:
<UserControl x:Class="WpfApplication1.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:CustomCommands="clr-namespace:WpfApplication1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="CustomCommands:myCustomCommand.Launch" Executed="CommandBinding_Executed">
</CommandBinding>
</UserControl.CommandBindings>
<Grid >
<TextBox Name="mytxt" Height="30" Width="60" Margin="50,50,50,50" ></TextBox>
<Button Name="b" Height="30" Width="60" Margin="109,152,109,78" Command="CustomCommands:ZenabUICommand.Launch"></Button>
</Grid>
Now in User control code
Handle command_executed
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
mytxt.Text = "invoked on custom command";
}
}
}

Categories