You want to use a custom Binding but the control does not support binding in the area you want. What are your options? Which would you choose and why?
For example, you have a textbox and you want to associate a command to it which is fired for every key up event. Also you want another command on the same textbox to be fired on key return. What can you do?
Answer:-
The easiest solution is to create an attached behavior. Let us create a class with a dependency property
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
namespace SU.Behaviours
{
public static class KeyUpBehaviour
{
public static DependencyProperty KeyUpCommandProperty = DependencyProperty.RegisterAttached("KeyUp",
typeof(ICommand),
typeof(KeyUpBehaviour),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(KeyUpBehaviour.KeyUpChanged)));
public static void SetKeyUp(DependencyObject target, ICommand value)
{
target.SetValue(KeyUpBehaviour.KeyUpCommandProperty, value);
}
public static ICommand GetKeyUp(DependencyObject target)
{
return (ICommand)target.GetValue(KeyUpCommandProperty);
}
private static void KeyUpChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
UIElement element = target as UIElement;
if (element != null)
{
// If we're putting in a new command and there wasn't one already
// hook the event
if ((e.NewValue != null) && (e.OldValue == null))
{
element.KeyUp += new KeyEventHandler(element_KeyUp);
}
// If we're clearing the command and it wasn't already null
// unhook the event
else if ((e.NewValue == null) && (e.OldValue != null))
{
element.KeyUp -= element_KeyUp;
}
}
}
static void element_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down || e.Key == Key.Up)
return;
UIElement element = (UIElement)sender;
ICommand command = (ICommand)element.GetValue(KeyUpBehaviour.KeyUpCommandProperty);
command.Execute(null);
}
}
//Creating our own Delegate Command
public sealed class DelegateCommand : ICommand
{
public delegate void SimpleEventHandler();
private SimpleEventHandler handler;
private bool isEnabled = true;
public event EventHandler CanExecuteChanged;
public DelegateCommand(SimpleEventHandler handler)
{
this.handler = handler;
}
private void OnCanExecuteChanged()
{
if (this.CanExecuteChanged != null)
{
this.CanExecuteChanged(this, EventArgs.Empty);
}
}
bool ICommand.CanExecute(object arg)
{
return this.IsEnabled;
}
void ICommand.Execute(object arg)
{
this.handler();
}
public bool IsEnabled
{
get
{
return this.isEnabled;
}
set
{
this.isEnabled = value;
this.OnCanExecuteChanged();
}
}
}
}
Similarly we can also have another one for key return:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
namespace SU.Behaviours
{
public static class KeyReturnBehaviour
{
public static DependencyProperty KeyReturnCommandProperty = DependencyProperty.RegisterAttached("KeyReturn",
typeof(ICommand),
typeof(KeyReturnBehaviour),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(KeyReturnBehaviour.KeyReturnChanged)));
public static void SetKeyReturn(DependencyObject target, ICommand value)
{
target.SetValue(KeyReturnBehaviour.KeyReturnCommandProperty, value);
}
public static ICommand GetKeyReturn(DependencyObject target)
{
return (ICommand)target.GetValue(KeyReturnCommandProperty);
}
private static void KeyReturnChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
UIElement element = target as UIElement;
if (element != null)
{
// If we're putting in a new command and there wasn't one already
// hook the event
if ((e.NewValue != null) && (e.OldValue == null))
{
element.KeyUp += new KeyEventHandler(element_KeyReturn);
}
// If we're clearing the command and it wasn't already null
// unhook the event
else if ((e.NewValue == null) && (e.OldValue != null))
{
element.KeyUp -= element_KeyReturn;
}
}
}
static void element_KeyReturn(object sender, KeyEventArgs e)
{
if (e.Key != Key.Return)
return;
UIElement element = (UIElement)sender;
ICommand command = (ICommand)element.GetValue(KeyReturnBehaviour.KeyReturnCommandProperty);
command.Execute(null);
}
}
}
Formatting Strings in XAML with multibinding
For example, you have a textbox and you want to associate a command to it which is fired for every key up event. Also you want another command on the same textbox to be fired on key return. What can you do?
Answer:-
The easiest solution is to create an attached behavior. Let us create a class with a dependency property
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
namespace SU.Behaviours
{
public static class KeyUpBehaviour
{
public static DependencyProperty KeyUpCommandProperty = DependencyProperty.RegisterAttached("KeyUp",
typeof(ICommand),
typeof(KeyUpBehaviour),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(KeyUpBehaviour.KeyUpChanged)));
public static void SetKeyUp(DependencyObject target, ICommand value)
{
target.SetValue(KeyUpBehaviour.KeyUpCommandProperty, value);
}
public static ICommand GetKeyUp(DependencyObject target)
{
return (ICommand)target.GetValue(KeyUpCommandProperty);
}
private static void KeyUpChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
UIElement element = target as UIElement;
if (element != null)
{
// If we're putting in a new command and there wasn't one already
// hook the event
if ((e.NewValue != null) && (e.OldValue == null))
{
element.KeyUp += new KeyEventHandler(element_KeyUp);
}
// If we're clearing the command and it wasn't already null
// unhook the event
else if ((e.NewValue == null) && (e.OldValue != null))
{
element.KeyUp -= element_KeyUp;
}
}
}
static void element_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down || e.Key == Key.Up)
return;
UIElement element = (UIElement)sender;
ICommand command = (ICommand)element.GetValue(KeyUpBehaviour.KeyUpCommandProperty);
command.Execute(null);
}
}
//Creating our own Delegate Command
public sealed class DelegateCommand : ICommand
{
public delegate void SimpleEventHandler();
private SimpleEventHandler handler;
private bool isEnabled = true;
public event EventHandler CanExecuteChanged;
public DelegateCommand(SimpleEventHandler handler)
{
this.handler = handler;
}
private void OnCanExecuteChanged()
{
if (this.CanExecuteChanged != null)
{
this.CanExecuteChanged(this, EventArgs.Empty);
}
}
bool ICommand.CanExecute(object arg)
{
return this.IsEnabled;
}
void ICommand.Execute(object arg)
{
this.handler();
}
public bool IsEnabled
{
get
{
return this.isEnabled;
}
set
{
this.isEnabled = value;
this.OnCanExecuteChanged();
}
}
}
}
Similarly we can also have another one for key return:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
namespace SU.Behaviours
{
public static class KeyReturnBehaviour
{
public static DependencyProperty KeyReturnCommandProperty = DependencyProperty.RegisterAttached("KeyReturn",
typeof(ICommand),
typeof(KeyReturnBehaviour),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(KeyReturnBehaviour.KeyReturnChanged)));
public static void SetKeyReturn(DependencyObject target, ICommand value)
{
target.SetValue(KeyReturnBehaviour.KeyReturnCommandProperty, value);
}
public static ICommand GetKeyReturn(DependencyObject target)
{
return (ICommand)target.GetValue(KeyReturnCommandProperty);
}
private static void KeyReturnChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
UIElement element = target as UIElement;
if (element != null)
{
// If we're putting in a new command and there wasn't one already
// hook the event
if ((e.NewValue != null) && (e.OldValue == null))
{
element.KeyUp += new KeyEventHandler(element_KeyReturn);
}
// If we're clearing the command and it wasn't already null
// unhook the event
else if ((e.NewValue == null) && (e.OldValue != null))
{
element.KeyUp -= element_KeyReturn;
}
}
}
static void element_KeyReturn(object sender, KeyEventArgs e)
{
if (e.Key != Key.Return)
return;
UIElement element = (UIElement)sender;
ICommand command = (ICommand)element.GetValue(KeyReturnBehaviour.KeyReturnCommandProperty);
command.Execute(null);
}
}
}
Formatting Strings in XAML with multibinding
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} x {1} Test">
<Binding ElementName="sl1" Path="Value" />
<Binding ElementName="sl2" Path="Value" />
</MultiBinding>
No comments:
Post a Comment