i have two usercontrols which is bound in MainWindow. What i want when MainWindow is Loaded, textbox1 which is in usercontrol1 should be focused automatically, and when i hit down arrow from keyboard textbox2 which is in usercontrol2 should be focused. And again on up arrow focus textbox1.
Below is MainWindow's xaml code`
<Window x:Class="FocusTextboxesFromMain.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:FocusTextboxesFromMain" Loaded="Window_Loaded"
mc:Ignorable="d"
Title="Focus Textboxes Testing" Height="450" Width="800">
<Grid>
<StackPanel>
<local:UserControl1/>
<local:UserControl2/>
</StackPanel>
</Grid>
Below is Usercontrol1's xaml code`
<UserControl
x:Class="FocusTextboxesFromMain.UserControl1"
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="clr-namespace:FocusTextboxesFromMain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="800"
Height="200"
mc:Ignorable="d">
<Grid Background="Red">
<TextBlock
FontSize="50"
Foreground="White"
Text="UserControl1" />
<TextBox
x:Name="textbox1"
Width="200"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="25" />
</Grid>
and below is Usercontrol2's xaml code`
<UserControl
x:Class="FocusTextboxesFromMain.UserControl2"
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="clr-namespace:FocusTextboxesFromMain"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="800"
Height="200"
mc:Ignorable="d">
<Grid Background="Green">
<TextBlock
FontSize="50"
Foreground="White"
Text="UserControl2" />
<TextBox
x:Name="textbox2"
Width="200"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="25" />
</Grid>
please note that i want all my logic in MainWindow Class, MvvM should not be involved
namespace FocusTextboxesFromMain
{
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Focus textbox1 of usercontrol1
}
// on down arrow then Focus textbox2 of usercontrol2
// and again on up arrow then Focus textbox1 of usercontrol1
}
}
sorry for bad explanation, thanks in advance
You can find what you are looking for in the answer of this question:
Moving to next control on Enter keypress in WPF
Just follow the code and create related event
public MainWindow()
{
InitializeComponent();
this.PreviewKeyDown += new KeyEventHandler(txtFirst_KeyDown);
this.PreviewKeyDown += new KeyEventHandler(txtSecond_KeyDown);
}
private void txtFirst_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Down)
{
txtSecond.Focus();
}
}
private void txtSecond_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Up)
{
txtFirst.Focus();
}
}
private void Window_Loaded_1(object sender, RoutedEventArgs e)
{
txtFirst.Focus();
}
Related
Running below code will open app in full screen. clicking on the width button should change app width to 500 but its not changing to smaller. Is there anything else need to add?
MainWindow.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"
WindowState="Maximized"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
SizeChanged="Window_SizeChanged">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox Text="500" x:Name="xwidth" Width="200" Margin="5"/>
<Button Content="width change" Click="Button_Click" Width="200"/>
</StackPanel>
</Window>
MainWindow.xaml.cs
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Width = System.Convert.ToDouble(xwidth.Text);
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
Console.WriteLine("changed " + System.Convert.ToString(this.Width));
}
}
}
WindowState is Maximized, change it to normal
private void Button_Click(object sender, RoutedEventArgs e){
WindowState = WindowState.Normal;
Width = Convert.ToDouble(xwidth.Text);
}
I have two UIElements. An Image inside a ViewBox and Canvas that overlays it. On both is registered MoseMove event in the code behind.
Currently is raised the event only on the element that is on the top.
Is there any way how to raise MouseMove on both UIElements?
XAML:
<Window x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid ClipToBounds="True">
<Viewbox Name="border" StretchDirection="Both" Stretch="Uniform" Panel.ZIndex="0" >
<Grid>
<Image Name="image" Panel.ZIndex="1" >
<Image.Source>
<BitmapImage UriSource="d:\test.png"/>
</Image.Source>
</Image>
</Grid>
</Viewbox>
<Canvas Name="canvas" Panel.ZIndex="2" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
</Window>
Code-behind:
using System.Windows;
using System.Windows.Input;
namespace WpfApp2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
border.PreviewMouseMove += Border_PreviewMouseMove;
canvas.PreviewMouseMove += Canvas_PreviewMouseMove;
}
private void Border_PreviewMouseMove(object sender, MouseEventArgs e)
{
//Not Raised...
}
private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
{
//Raised...
}
}
}
You can try this :)
private void Canvas_PreviewMouseMove(object sender, MouseEventArgs e)
{
border.RaiseEvent(e);
}
I have the following, working code:
<Window x:Class="GemTowerDefense.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:GemTowerDefense"
mc:Ignorable="d"
Title="Gem Tower Defense" Height="670" Width="800"
Loaded="Window_Loaded">
<Window.Resources>
<local:GameControl x:Key="MyGameControl"/>
</Window.Resources>
<Grid>
<Border Background="Gray" Height="600" Width="600" Margin="3,26,189,3">
<local:GameControl/>
</Border>
</Grid>
</Window>
Here you can see that I have the "local:GameControl" duplicated. This is because I only had the GameControl inside the "Grid" and the "Border". Everything worked fine, I implemented OnRender inside GameControl, it draws out everything I want it to.
My problem is, that I want this local:GameControl to interact with the MainWindow's buttons:
<Button Click="Life_Button_Click" Content="Buy 1 Life" HorizontalAlignment="Left" Margin="608,26,0,0" VerticalAlignment="Top" Width="170"/>
<Button Click="Upgrade_Button_Click" Content="Upgrade Chances" HorizontalAlignment="Left" Margin="608,51,0,0" VerticalAlignment="Top" Width="170"/>
<Button Click="Place_Button_Click" Content="Place Gems" HorizontalAlignment="Left" Margin="608,156,0,0" VerticalAlignment="Top" Width="170"/>
So I added this inside "Grid". But inside the Button Click Event Handlers, I don't know how to reach GameControl.
What I want to do is something like this:
public partial class MainWindow : Window
{
GameControl control { get; set; }
private void Life_Button_Click(object sender, RoutedEventArgs e)
{
control.BuyLife();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
control = Application.Current.MainWindow.Resources["MyGameControl"] as GameControl;
}
}
How can I achieve this to work?
This doesn't work obviously, because I cannot name GameControl with an x:Key, only if I add it as a resource, but then I dont know how to refer to it as a FrameworkElement in the xaml code.
Give the control an x:Name:
<Border Background="Gray" Height="600" Width="600" Margin="3,26,189,3">
<local:GameControl x:Name="control" />
</Border>
You can then access it in the code-behind:
private void Life_Button_Click(object sender, RoutedEventArgs e)
{
control.BuyLife();
}
I accidentally found this while working with my project, but I was able to reproduce this in a base project:
I open a MainWindow, then with ShowDialog a child window, Owner set to the Main. When I click on the Main, the Child starts to flash, then I start clicking between the Main and the Child very fast, and sometimes the Main gets the focus, then I able to open another Child window.
MainWindow:
<Window x:Class="WpfShowDialog.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="300" WindowStartupLocation="CenterScreen" >
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
<TextBlock Text="MainWindow" Margin="10" />
<Button Content="Open child" Margin="10" Click="Button_Click" />
</StackPanel>
</Window>
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var childWindow = new ChildWindow()
{
Owner = this
};
childWindow.ShowDialog();
}
}
ChildWindow:
<Window x:Class="WpfShowDialog.ChildWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ChildWindow" Height="150" Width="200" WindowStartupLocation="CenterOwner">
<Grid>
<TextBlock Text="ChildWindow" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Window>
Code behind:
public partial class ChildWindow : Window
{
public ChildWindow()
{
InitializeComponent();
}
}
I click on between these red circles:
Is this some kind of bug, or I miss something?
I have a window with a button and usercontrol. Now when I click on the button, the raised event, I wanna catch on usercontrol. I guess this principle it called event tunneling. But I don't know too, if this way would be the right way to catch the button click event.
Example
<Window x:Class="EventTunneling.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:EventTunneling"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Click me"></Button>
<uc:Control Grid.Row="1"></uc:Control>
</Grid>
</Window>
UserControl
<UserControl x:Class="EventTunneling.Control"
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>
</Grid>
</UserControl>
Now i want to catch the event on the partial class of usercontrol, that was raised from main window. How can i do that?
namespace EventTunneling
{
/// <summary>
/// Interaction logic for Control.xaml
/// </summary>
public partial class Control : UserControl
{
public Control()
{
InitializeComponent();
}
}
}
Unfortunately, you're doing this all wrong. First, you need to data bind your collection from the code behind to the DataGrid.ItemsSource property. Then, when the Button is clicked, just handle it in the code behind, where you have access to the collection and simply save it however you like:
In UserControl:
<DataGrid ItemsSource="{Binding Items}" ... />
In MainWindow:
<Button Grid.Row="0" Content="Click me" Click="Button_Click" />
In code behind (you should implement the INotifyPropertyChanged interface on this property):
public ObservableCollection<YourDataType> Items { get; set; }
...
private void Button_Click(object sender, RoutedEventArgs e)
{
SaveAsXml(Items);
}
In code behind constructor (or set it in any valid way you prefer):
DataContext = this;
Make a public event on the window.
Fire the event when the button is clicked.
Subscribe to the event from your control
you can simply do this when the button is clicked make a call to a public method in your user Control :
namespace EventTunneling
{
public partial class Control : UserControl
{
public Control()
{
InitializeComponent();
}
public void CatchEventOnUserControl()
{
//do your job here
//....
}
}
}
then when the button is clicked call the CatchEventOnUserControl method
<Window x:Class="EventTunneling.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:EventTunneling"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Click me" Click="Button_Click"></Button>
<uc:Control x:Name="mycontrol" Grid.Row="1"></uc:Control>
</Grid>
and the code behind is
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
mycontrol.CatchEventOnUserControl();
}
}