How to read TextBox focus from ViewModel - MVVM Light - c#

I have two textBoxes and in my ViewModel I would like to be able to keep track of which box is currently in focus.
<TextBox x:Name="textBox1" Text="Text Box 1"/>
<TextBox x:Name="textBox2" Text="Text Box 2"/>
How can I read/identify which textBox is currently in focus from my ViewModel?

There are several ways how you can achieve this, some of them:
1) Use behavior:
You need System.Windows.Interactivity.dll
Behavior (setting IsFocused property will not make element focused, you need slightly extend behavior in order to achieve this)
public class FocusChangedBehavior : Behavior<UIElement>
{
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.Register(
nameof(IsFocused),
typeof(bool),
typeof(FocusChangedBehavior),
new FrameworkPropertyMetadata(default(bool),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool IsFocused
{
get { return (bool)this.GetValue(IsFocusedProperty); }
set { this.SetValue(IsFocusedProperty, value); }
}
/// <inheritdoc />
protected override void OnAttached()
{
this.AssociatedObject.GotFocus += this.AssociatedObjectFocused;
this.AssociatedObject.LostFocus += this.AssociatedObjectUnfocused;
}
/// <inheritdoc />
protected override void OnDetaching()
{
this.AssociatedObject.GotFocus -= this.AssociatedObjectFocused;
this.AssociatedObject.LostFocus -= this.AssociatedObjectUnfocused;
}
private void AssociatedObjectFocused(object sender, RoutedEventArgs e)
{
this.IsFocused = true;
}
private void AssociatedObjectUnfocused(object sender, RoutedEventArgs e)
{
this.IsFocused = false;
}
}
In XAML you bind IsFocused to property in ViewModel.
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<TextBox x:Name="textBox1" Text="Text Box 1">
<i:Interaction.Behaviors>
<local:FocusChangedBehavior IsFocused="{Binding IsFocusedTxt1}" />
</i:Interaction.Behaviors>
</TextBox>
<TextBox x:Name="textBox2" Text="Text Box 2">
<i:Interaction.Behaviors>
<local:FocusChangedBehavior IsFocused="{Binding IsFocusedTxt2}" />
</i:Interaction.Behaviors>
</TextBox>
Finally in View-Model create properties
public bool IsFocusedTxt1 { get; set; }
public bool IsFocusedTxt2 { get; set; }
2) Alternatively you could you use EventTrigger in the XAML
You need System.Windows.Interactivity.dll and MicrosoftExpressionInteractions (For the ActionCommand)
Event Triggers:
<TextBox x:Name="textBox1" Text="Text Box 1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding NotifyFocusedReceivedTxt1Command}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
In ViewModel create command NotifyFocusedReceivedTxt1Command
public ICommand NotifyFocusedReceivedTxt1Command { get; }
// in constructor
this.NotifyFocusedReceivedTxt1Command = new ActionCommand(this.FocusedReceivedTxt1);
// and method
private void FocusedReceivedTxt1()
{
// Your logic
}
Also, if you don't want introduce many command/properties you could use same command and pass different textboxes by setting CommandParameter (slightly breaks MVVM, but not critically)
<TextBox x:Name="textBox1" Text="Text Box 1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding NotifyFocusedReceivedCommand}"
CommandParameter="{Binding ., ElementName=textBox1}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBox x:Name="textBox2" Text="Text Box 2">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding NotifyFocusedReceivedCommand}"
CommandParameter="{Binding ., ElementName=textBox2}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
and
public ICommand NotifyFocusedReceivedCommand { get; }
// in constructor
this.NotifyFocusedReceivedCommand = new ActionCommand(this.FocusedReceived);
// and method
private void FocusedReceived(object control)
{
var txt = (TextBox)control;
bool isFocused = txt.IsFocused;
string name = txt.Name;
}

public static DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(TextBoxProperties),
new UIPropertyMetadata(false,OnIsFocusedChanged)
);
public static bool GetIsFocused(DependencyObject dependencyObject) {
return (bool)dependencyObject.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject dependencyObject, bool value) {
dependencyObject.SetValue(IsFocusedProperty, value);
}
you can use this property

This can not be done via the ViewModel on Server-side, a workaround would look like this:
View Code: (js & html)
function updateFocus(textboxNr) {
$.ajax({
type: "POST",
url: '#Url.Action("Index", "Controller")',
data: {
Focus: textboxNr
},
contentType: "application/json; charset=utf-8",
dataType: "json",
});
}
<textarea id="1" name="1" onfocus="updateFocus(1)">Text Box 1</textarea>
<textarea id="2" name="2" onfocus="updateFocus(2)">Text Box 2</textarea>

Related

Why is my manual call to PropertyChange ignored?

I have a ComboBox that is bound to a list of archiver plug-ins, the selected item is inside this window (no MVVM). I also use one of the selected items properties as content of a ContentPresenter. And last but not least there is a CheckBox that should be en- or disabled depending on another property of this selected item. This is my code (at least the important parts):
XAML:
<ComboBox ItemsSource="{Binding Archiver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
DisplayMemberPath="ShortName" SelectedValuePath="ID" SelectedValue="{Binding [ArchiveService].Value, Mode=TwoWay}"
Name="ArchiveServiceCB" SelectedItem="{Binding SelectedArchiver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
<ContentPresenter Content="{Binding SelectedArchiver.ConfigControl, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
<CheckBox Style="{StaticResource CheckBoxDefaultStyle}" Content="{x:Static base:AppStrings.DeleteSourceAfterArchive}" IsChecked="{Binding [DeleteSourceAfterArchive].Value, Mode=TwoWay}"
IsEnabled="{Binding SelectedArchiver.AllowDeleteSourceFile, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
C# of window:
public ObservableCollection<MasterArchiver> Archiver { get; } = new ObservableCollection<MasterArchiver>();
private MasterArchiver _selectedArchiver = null;
public MasterArchiver SelectedArchiver
{
get => _selectedArchiver;
set
{
if (_selectedArchiver != value)
{
_selectedArchiver = value;
OnPropertyChanged(nameof(SelectedArchiver));
}
}
}
C# of archiver class:
public UserControl ConfigControl { get; } = new DefaultFileArchiverConfigControl();
public bool AllowDeleteSourceFile => DocType != null && !DocType["Archive_OverwriteSource"];
private DocType _docType = null;
public DocType DocType
{
get => _docType;
set
{
if (_docType != value)
{
if (_docType != null)
{
_docType.ConfigPropertyChanged -= new EventHandler<ConfigPropertyChangedEventArgs>(DocType_ConfigPropertyChanged);
}
_docType = value;
OnPropertyChanged(nameof(DocType));
OnPropertyChanged(nameof(AllowDeleteSourceFile));
if (_docType != null)
{
_docType.ConfigPropertyChanged += new EventHandler<ConfigPropertyChangedEventArgs>(DocType_ConfigPropertyChanged);
}
}
}
}
public DefaultFileArchiver()
{
((DefaultFileArchiverConfigControl)ConfigControl).Owner = this;
}
private void DocType_ConfigPropertyChanged(object sender, ConfigPropertyChangedEventArgs e)
{
if (e.PropertyName == "Archive_OverwriteSource")
{
OnPropertyChanged(nameof(AllowDeleteSourceFile));
}
}
XAML of ConfigControl:
<UserControl x:Class="ArchiveProject.Data.DefaultFileArchiverConfigControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:base="clr-namespace:ArchiveProject.Base;assembly=ArchiveProject.Base"
DataContext="{Binding Owner, RelativeSource={RelativeSource Self}}">
<Grid DataContext="{Binding DocType}">
<RadioButton Grid.Row="0" GroupName="FileArchiveDest" Content="{x:Static base:AppStrings.ArchiveUseSource}"
IsChecked="{Binding [Archive_OverwriteSource].Value, Converter={StaticResource RadioButtonCheckedConverter}, ConverterParameter={StaticResource True}}" />
<RadioButton Grid.Row="1" Grid.Column="0" GroupName="FileArchiveDest" Name="ArchiveNotUseSourceRB" Content="{x:Static base:AppStrings.ArchiveFileName}"
IsChecked="{Binding [Archive_OverwriteSource].Value, Converter={StaticResource RadioButtonCheckedConverter}, ConverterParameter={StaticResource False}}" />
Inside the code of the ConfigControl is only a DependencyProperty with standard values of type DefaultFileArchiver and name Owner.
When I now change the Archive_OverwriteSource setting inside the DocTypeConfigControl of the ContentPresenter there is a property changed event, that calls the DocType_ConfigPropertyChanged handler. But the OnPropertyChanged is ignored. The AllowDeleteSourceFile getter is not called from the window. If I change the archiver inside the ComboBox all bindings are re-evaluated. But I have to disable the CheckBox when the Archive_OverwriteSource inside the bound DocType is changed.
Anyone an idea how to find the error? There are no shown XAML Binding Failures in VS.
p.s.: I implemented in all classes the INotifyPropertyChanged interface.
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

How to trigger KeyUp Event in MVVM using ICommand

I have created this simple view:
Now when I press the RETURN key while the cursor being inside one of these 2 textboxes, I want the "Suchen" = SEARCH button to trigger (KeyUp Event).
I know how to easily do this in the code behind but I want to do it in MVVM (in my view model class) with an ICommand. In the code behind I used the (autogenerated) KeyEventArgs parameter.
I tried it in MVVM using ICommand but the Command method gives me an error claiming that I would need to instantiate an object for the KeyEventArgs argument. In the code behind (non-mvvm-like) I did not need to instantiate anything because the KeyEventArgs parameter was "autogenerated" just like the method. So I didn't have to worry about that.
How do I make the KeyUp event work in my MVVM project?
For this question to answer I provide you the following shortened code:
XAML-View:
<StackPanel Height="423" VerticalAlignment="Bottom">
<Label Name="lblArtikelbezeichnung" Content="Artikelbezeichnung:" Margin="20, 20, 20, 0"></Label>
<TextBox Name="txtArtikelbezeichnung"
Width="Auto"
Margin="20, 0, 20, 0"
IsEnabled="{Binding BezEnabled}"
Text="{Binding BezText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedBez}" />
</i:EventTrigger>
<i:EventTrigger EventName="KeyUp">
<i:InvokeCommandAction Command="{Binding KeyUpBez}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<!--TextChanged="txtArtikelbezeichnung_TextChanged"
KeyUp="txtArtikelbezeichnung_KeyUp"-->
<Label Name="lblLieferant" Content="Lieferant:" Margin="20, 0, 20, 0"></Label>
<TextBox Name="txtLieferant"
Width="Auto"
Margin="20, 0, 20, 0"
IsEnabled="{Binding LiefEnabled}"
Text="{Binding LiefText}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedLief}" />
</i:EventTrigger>
<i:EventTrigger EventName="KeyUp">
<i:InvokeCommandAction Command="{Binding KeyUpLief}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<!--TextChanged="txtLieferant_TextChanged"
KeyUp="txtLieferant_KeyUp"-->
<Button Name="btnSuchen"
Content="Suchen"
Width="100" Height="25"
Margin="20, 10,240, 10"
Command="{Binding GefilterteSuche}">
</Button>
...
<StackPanel>
Code Behind:
using System.Windows;
namespace Lieferscheine
{
/// <summary>
/// Interaktionslogik für artikelHinzu.xaml
/// </summary>
public partial class artikelHinzu : Window
{
public artikelHinzu()
{
InitializeComponent();
DataContext = new ArtikelHinzuViewModel();
}
}
}
View Model:
public class ArtikelHinzuViewModel : INotifyPropertyChanged
{
//ICommands (shortened)
public ICommand GefilterteSuche => new DelegateCommand<object>(SucheArtikel);
public ICommand KeyUpLief => new DelegateCommand<KeyEventArgs>(KeyUpLieferant);
public ICommand KeyUpBez => new DelegateCommand<KeyEventArgs>(KeyUpBezeichnung);
//INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//Konstruktor
public ArtikelHinzuViewModel()
{
}
//ICommand methods (shortened for reasons of simplicity)
//KeyUp Events (THIS PART IS MY PROBLEM)
private void KeyUpBezeichnung(KeyEventArgs e) //the argument is obligatory but it does not have an instantiated object which is why an error fires...
{
//since I need to create an object for KeyEventArgs I tried this but it is useless...
/*e = new KeyEventArgs(Keyboard.PrimaryDevice,
Keyboard.PrimaryDevice.ActiveSource,
0, Key.Back);
//I need to access this e.Key property but don't know how in my case! That is the actual problem...
if (e.Key == Key.Return)
{
object o = new object();
SucheArtikel(o);
}
*/
}
//same problem here as above...
private void KeyUpLieferant(KeyEventArgs e)
{
/*
e = new KeyEventArgs(Keyboard.PrimaryDevice,
Keyboard.PrimaryDevice.ActiveSource,
0, Key.Back);
if (e.Key == Key.Return)
{
object o = new object();
SucheArtikel(o);
}
*/
}
}
Using InputBindings is easier:
<TextBox>
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SearchCommand}" />
</TextBox.InputBindings>
</TextBox>

WPF Override / Reset Keybinding on child control

I have a window on which I have commands bound to the numpad keys like this:
<!-- Set keybindings -->
<controls:MetroWindow.InputBindings>
<!-- NumPad Shortcuts for selecting reasons -->
<KeyBinding Key="NumPad0" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="0" />
<KeyBinding Key="NumPad1" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="1" />
<KeyBinding Key="NumPad2" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="2" />
<KeyBinding Key="NumPad3" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="3" />
<KeyBinding Key="NumPad4" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="4" />
<KeyBinding Key="NumPad5" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="5" />
<KeyBinding Key="NumPad6" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="6" />
<KeyBinding Key="NumPad7" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="7" />
<KeyBinding Key="NumPad8" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="8" />
<KeyBinding Key="NumPad9" Command="{Binding OnReasonShortcutKeyPressedCommand}" CommandParameter="9" />
<!-- Others -->
<KeyBinding Key="Back" Command="{Binding OnReasonGoBackClickedCommand}" />
<KeyBinding Key="Escape" Command="{Binding OnEscapeClickedCommand}" />
</controls:MetroWindow.InputBindings>
In the backend, this is handled as:
ICommand _onReasonShortcutKeyPressedCommand;
public ICommand OnReasonShortcutKeyPressedCommand
{
get
{
return _onReasonShortcutKeyPressedCommand ??
(_onReasonShortcutKeyPressedCommand = new RelayCommand(OnReasonShortcutKeyPressedCommand_Execute));
}
}
private void OnReasonShortcutKeyPressedCommand_Execute(object param)
{
//Find which key was presses by command param
int keyPressed = Int32.Parse((string)param);
// Do something bla bla bla
}
Now, this window also contains some textboxes in which numbers have to be entered. Ofcourse, the keybindings on the window level result in the commands being triggered instead of the actual number being printed. Is there anyway in which I can override this?
Not sure whether there is better way to solve this, but my propose is to use attach property to archive this.
Here is example:
In XAML you should attach new behavior (LimitBindings) to TextBox:
XAML:
<TextBox behavs:KeyBindingBehavior.LimitKeyBindings="True"></TextBox>
and create your behavior class (+ Helper method to get parent window -it should be placed somewhere else :)):
public static class KeyBindingBehavior
{
//to keep window's bindings.
private static InputBindingCollection windowBindings;
public static bool GetLimitKeyBindings(DependencyObject obj)
{
return (bool)obj.GetValue(LimitKeyBindingsProperty);
}
public static void SetLimitKeyBindings(DependencyObject obj, bool value)
{
obj.SetValue(LimitKeyBindingsProperty, value);
}
public static readonly DependencyProperty LimitKeyBindingsProperty =
DependencyProperty.RegisterAttached(
"LimitKeyBindings",
typeof(bool),
typeof(KeyBindingBehavior),
new PropertyMetadata(false, PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
TextBox textBox = dependencyObject as TextBox;
if (textBox != null)
{
textBox.GotKeyboardFocus += textBox_GotKeyboardFocus;
textBox.LostKeyboardFocus += textBox_LostKeyboardFocus;
}
}
static void textBox_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
var window = GetParentWindow(sender as DependencyObject);
window.InputBindings.AddRange(windowBindings);
}
static void textBox_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
var window = GetParentWindow(sender as DependencyObject);
windowBindings = new InputBindingCollection(window.InputBindings);
window.InputBindings.Clear();
}
// This helper method should be in seperate class
public static Window GetParentWindow(DependencyObject child)
{
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null)
{
return null;
}
Window parent = parentObject as Window;
if (parent != null)
{
return parent;
}
else
{
return GetParentWindow(parentObject);
}
}
}
Don't forget to add reference in XAML to point to behavior class :
xmlns:behavs="clr-namespace:WpfApplication1"

Bind events to Item ViewModel

I have a ListView/GridView setup and I want to handle a right click on the dislayed items. Is there are Databinding-way of doing this? I have seen complicated workarounds like handling the super-elements event and poking around to find its origin, but that feels awfully bloated for such basic request.
What I'd love to see is something like binding the event to an action of the item's ViewModel - is there a way to do that? Similar to this, but I can't quite wrap my head around how to adapt that to work on a single ListView item (I am not even sure that's possible, tbh).
Rough outline:
<ListView>
<ListView.View>
<GridView />
</ListView.View>
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
</Style>
</ListView.Resources>
</ListView/>
There is a way using the Interactivity assembly form the Blend SDK. It will provide an EventTrigger which executes a command when an event is raised.
<!--
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
-->
<Button Content="Click me">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Edit:
A possible solution for your problem could look like this:
View:
<ListView x:Name="listView">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseRightButtonUp">
<i:InvokeCommandAction Command="{Binding RightClickOnItemCommand}"
CommandParameter={Binding SelectedItem, ElementName=listView} />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
ViewModel:
public ICommand RightClickOnItemCommand { get; set; }
public void RightClickOnItem(object item)
{
}
You could try to create a style template for the list view item, and add an attached behaviour to it to handle mouse clicks.
public static readonly DependencyProperty PreviewMouseLeftButtonDownCommandProperty =
DependencyProperty.RegisterAttached("PreviewMouseLeftButtonDownCommand", typeof (ICommand),
typeof (MouseBehaviour), new FrameworkPropertyMetadata(PreviewMouseLeftButtonDownCommandChanged));
private static void PreviewMouseLeftButtonDownCommandChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs args)
{
var element = (FrameworkElement) dependencyObject;
element.PreviewMouseLeftButtonDown += Element_PreviewMouseLeftButtonDown;
}
private static void Element_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
{
var element = (FrameworkElement) sender;
ICommand command = GetPreviewMouseLeftButtonDownCommand(element);
if (command != null)
{
command.Execute(args);
}
}
public static void SetPreviewMouseLeftButtonDownCommand(UIElement element, ICommand value)
{
element.SetValue(PreviewMouseLeftButtonDownCommandProperty, value);
}
public static ICommand GetPreviewMouseLeftButtonDownCommand(UIElement element)
{
return (ICommand) element.GetValue(PreviewMouseLeftButtonDownCommandProperty);
}

Pass KeyUp as parameter WPF Command Binding Text Box

I've a Text box KeyUp Event Trigger Wired up to a command in WPF.
I need to pass the actual key that was pressed as a command parameter.
The command executes fine, but the code that handles it needs to know the actual key that was pressed (remember this could be an enter key or anything not just a letter, so I can't get it from the TextBox.text).
Can't figure out how to do this.
XAML:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
XAML:
<TextBox Height="23" Name="TextBoxSelectionSearch" Width="148" Tag="Enter Selection Name" Text="{Binding Path=SelectionEditorFilter.SelectionNameFilter,UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyUp">
<i:InvokeCommandAction Command="{Binding SelectionEditorSelectionNameFilterKeyUpCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
I don't think that's possible with InvokeCommandAction but you can quickly create your own Behavior which could roughly look like this one:
public class KeyUpWithArgsBehavior : Behavior<UIElement>
{
public ICommand KeyUpCommand
{
get { return (ICommand)GetValue(KeyUpCommandProperty); }
set { SetValue(KeyUpCommandProperty, value); }
}
public static readonly DependencyProperty KeyUpCommandProperty =
DependencyProperty.Register("KeyUpCommand", typeof(ICommand), typeof(KeyUpWithArgsBehavior), new UIPropertyMetadata(null));
protected override void OnAttached()
{
AssociatedObject.KeyUp += new KeyEventHandler(AssociatedObjectKeyUp);
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.KeyUp -= new KeyEventHandler(AssociatedObjectKeyUp);
base.OnDetaching();
}
private void AssociatedObjectKeyUp(object sender, KeyEventArgs e)
{
if (KeyUpCommand != null)
{
KeyUpCommand.Execute(e.Key);
}
}
}
and then just attach it to the TextBox:
<TextBox Height="23" Name="TextBoxSelectionSearch" Width="148" Tag="Enter Selection Name" Text="{Binding Path=SelectionEditorFilter.SelectionNameFilter,UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Behaviors>
<someNamespace:KeyUpWithArgsBehavior
KeyUpCommand="{Binding SelectionEditorSelectionNameFilterKeyUpCommand}" />
</i:Interaction.Behaviors>
</TextBox>
With just that you should receive the Key as a parameter to the command.

Categories