Access to PreviewKeyDown event of richTextBox in userControl - wpf

I would like to know how can I get access to event PreviewKeyDown of RichTextBox in UserControl.
For example, I have user Control and in this user control I have only one richTextBox:
Something like this:
<UserControl x:Class="Spirit.Controls.RichTextBoxControl"
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:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<toolkit:RichTextBox Name="RichTextBox"
Grid.Row="0" PreviewKeyDown="?">
</toolkit:RichTextBox>
</Grid>
</UserControl>
I use this control in WPF window.
<Window x:Class="WpfApplication2.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:WpfApplication2.Controls" xmlns:WpfApplication2="clr-namespace:WpfApplication2" Title="Window2" Height="300" Width="300">
<Grid>
<Spirit.Controls:RichTextBoxControl Background="Red"
FontSize="13"
Margin="4,4,4,4"
Grid.Row="0"
Here I would like to acces to PreviewKeyDown of richTextBox/>
</Grid>
</Window>
I would like have access to PreviewKeyDown of richTextBox, bind some method on this event and have access to KeyEventArgs.
Something like this:
private void RichTextBoxInUserControl_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter )
{
//...
}
}

I noticed the Intellisence wasn't picking up on RichTextBox... in Window but you can subscribe to that event like this
<Spirit.Controls:RichTextBoxControl
Name="RichTextBoxInUserControl"
Background="Red"
FontSize="13"
Margin="4,4,4,4"
Grid.Row="0"
RichTextBox.PreviewKeyDown="RichTextBoxInUserControl_PreviewKeyDown"/>
where RichTextBox is the Name of the toolkit:RichTextBox specified in your UserControl

Related

WPF DataGrid MouseLeftButtonUp get fired when maximizing window by double click on title

When I maximize the window by double click the title bar, my DataGrid get expanded and the MouseLeftButtonUp event is fired unintentionally.
I used MouseLeftButtonUp to detect which cell has been clicked. In this case, I want to maximize the window instead of clicking element inside DataGrid.
How can I prevent it from firing when user is maximizing the window or distinguish it from normal user click on DataGrid? ClickCount equals to 1 in this case.
Here is my code
MainWindow.xaml:
<Window x:Class="testing.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:testing"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid MouseLeftButtonUp="MouseSingleClick">
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs:
private void MouseSingleClick(object sender, MouseButtonEventArgs e)
{
Console.WriteLine($"Click: {e.ClickCount}");
}
Thanks.
Try use MouseLeftButtonDown event instead of up event
<Window x:Class="testing.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:testing"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="grdDB" MouseLeftButtonDown="grdDB_MouseLeftButtonDown">
</DataGrid>
</Grid>
MainWindow.xaml.cs
private void grdDB_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show($"Click: {e.ClickCount}");
}

WPF MVVM disable focus on ContentControl (with the Tab key)

I have a window with a ContentControl binding:
<ContentControl Content="{Binding CurrentViewModel}" />
I also have an empty user control binds to the ContentControl:
<UserControl x:Class="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>
</Grid>
</UserControl>
When I run and press the tab keyboard I get a dotted rectangle around the content control. How can I disable this?
I tried using Focusable="False" and FocusVisualStyle="{x:Null}" without success...
Have you tried setting IsTabStop="False", for example...
<ContentControl Height="200" Width="200" IsTabStop="False">
<ContentControl.Content>
<TextBox/>
</ContentControl.Content>
</ContentControl>
and I would suggest you combine it with this trick:
Loaded += (sender, e) =>
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
from the answer to this question: WPF and initial focus
Override the ContentControl Style and add property FocusVisualStyle as null and implement by using style property
<ContentControl Height="200" Width="200" FocusVisualStyle="{x:Null}">
<ContentControl.Content>
<local:UserControl1/>
</ContentControl.Content>
</ContentControl>

Changing content dynamically in wpf window

What i want to do is change/slide the content of a wpf window on the click of a button. I am new to wpf and have no clue how to do this. Please, if anyone can help me, I will be so grateful. Any video tutorials would be best.
You can put the content of the window into a UserControl. Your window then only has a content-control and a button to change the content. On a click on the button you can reassign the content-property of the content-control.
I've made a small example for this.
The XAML-Code for your MainWindow can look like this:
<Window x:Class="WpfApplication3.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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="Switch" Click="ButtonClick"/>
<ContentControl x:Name="contentControl" Grid.Row="1"/>
</Grid>
</Window>
I've added two UserControls to the solution. The CodeBehind for the MainWindow looks like:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.contentControl.Content = new UserControl1();
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
this.contentControl.Content = new UserControl2();
}
}
Update
I've created a small usercontrol called MyUserControl. The xaml-markup looks like
<UserControl x:Class="WpfApplication.MyUserControl"
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">
<StackPanel Orientation="Vertical">
<Label Content="This is a label on my UserControl"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Button Content="Testbutton 1" Margin="5"/>
<Button Content="Testbutton 2" Margin="5"/>
</StackPanel>
<CheckBox Content="Check Me"/>
</StackPanel>
</UserControl>
In the button-click-event above you can assign a new instance of this usercontrol to the content-control. This you can do by:
this.contentControl.Content = new MyUserControl();

UserControl Canvas.Left binding doesnt work

So the problem is this. I need UserControl which will have set Canvas.Top and Canvas.Left but these properties are binded from the ViewModel. For simplicity let's have this code for the user control with no code behind:
<UserControl x:Class="BadBinding.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Canvas.Left="{Binding ElementName=slider, Path=Value}"
>
<Grid Width="100" Background="Red">
<Slider x:Name="slider" Minimum="100" Maximum="250" />
</Grid>
</UserControl>
And this code for the main window:
<Window x:Class="BadBinding.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"
xmlns:local="clr-namespace:BadBinding"
>
<Canvas>
<local:MyUserControl />
</Canvas>
</Window>
I don't know why is binding not working. When you set Canvas.Left directly to some value everything is fine as well as writing content of the user control directly to the main window.
I think its because the UserControl is constructed befor being added to the Canvas and since Canvas.Left is an attached property it probably won't resolve correctly.
Try using a Reference binding.
<UserControl x:Class="BadBinding.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Canvas.Left="{Binding Source={x:Reference Name=slider}, Path=Value}"
>
<Grid Width="100" Background="Red">
<Slider x:Name="slider" Minimum="100" Maximum="250" />
</Grid>
</UserControl>
Note: you may get a compile warning, but it will still compile.
But I think the best option would be to create a property on your usercontrol to bind the value, this will also work.
I tried a lot with Bindings but it dint worked for me too.. so if you wanna go with EventHandler then the following workaround may help you..
Remove the Bindings and add an event handler to ValueChanged event
In your MyUserControl.xaml
<UserControl x:Class="BadBinding.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Width="100" Background="Red">
<Slider x:Name="slider" Minimum="100" Maximum="250" ValueChanged="slider1_ValueChanged" />
</Grid>
</UserControl>
In your MyUserControl.xaml.cs
private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Canvas.SetLeft(this, slider1.Value);
}
I tried this and working for me if you find any problem then let me know..

Add a user control to a wpf window

I have a user control that I've created, however when I go to add it to the XAML in the window, Intellisense doesn't pick it up, and I can't figure out how to add it to the window.
You need to add a reference inside the window tag. Something like:
xmlns:controls="clr-namespace:YourCustomNamespace.Controls;assembly=YourAssemblyName"
(When you add xmlns:controls=" intellisense should kick in to make this bit easier)
Then you can add the control with:
<controls:CustomControlClassName ..... />
You probably need to add the namespace:
<Window x:Class="UserControlTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UserControlTest"
Title="User Control Test" Height="300" Width="300">
<local:UserControl1 />
</Window>
Make sure there is an namespace definition (xmlns) for the namespace your control belong to.
xmlns:myControls="clr-namespace:YourCustomNamespace.Controls;assembly=YourAssemblyName"
<myControls:thecontrol/>
This is how I got it to work:
User Control WPF
<UserControl x:Class="App.ProcessView"
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>
User Control C#
namespace App {
/// <summary>
/// Interaction logic for ProcessView.xaml
/// </summary>
public partial class ProcessView : UserControl // My custom User Control
{
public ProcessView()
{
InitializeComponent();
}
} }
MainWindow WPF
<Window x:Name="RootWindow" x:Class="App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:App"
Title="Some Title" Height="350" Width="525" Closing="Window_Closing_1" Icon="bouncer.ico">
<Window.Resources>
<app:DateConverter x:Key="dateConverter"/>
</Window.Resources>
<Grid>
<ListView x:Name="listView" >
<ListView.ItemTemplate>
<DataTemplate>
<app:ProcessView />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Window>

Resources