In this post i will explain what are the new changes and improvements done in Data Binding in WPF 4.0
InputBinding
InputBinding was available in previous versions and the limitation was not able to bind Command property of InputBinding class. In WPF 4.0, InputBinding.Command property implemented as Dependency Property. Not only Command but KeyBinding.Key, KeyBinding.Modifiers, MouseBinding.MouseAction, InputBinding.CommandParameter and InputBinding.CommandTarget properties also implemented as Dependency Property so these all properties are now bindable.
Please have a look on below example of binding command property of InputBinding.
<Window x:Class="WPFTestApplication.InputBindingsImprovements"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFTestApplication"
Title="Command Binding Improvements" Height="200" Width="200">
<Grid>
<Button Content="Hit Me!"
Command="{Binding MyCommand}"
Height="30" Width="150">
<Button.InputBindings>
<KeyBinding
Command="{Binding MyCommand}"
Key="{Binding MyCommand.KeyGesture}"
Modifiers="{Binding MyCommand.ModifierKey}" />
<MouseBinding
Command="{Binding MyCommand}"
MouseAction="{Binding MyCommand.MouseActions}" />
</Button.InputBindings>
</Button>
</Grid>
</Window>
CodeBehind
public partial class InputBindingsImprovements : Window
{
public InputBindingsImprovements()
{
InitializeComponent();
mycommand = new BaseCommand((str) => MessageBox.Show("Hello"));
mycommand.KeyGesture = Key.H;
mycommand.ModifierKey = ModifierKeys.Control;
mycommand.MouseActions = MouseAction.RightClick;
DataContext = this;
}
private BaseCommand mycommand;
public BaseCommand MyCommand
{
get { return mycommand; }
}
}
public class BaseCommand : ICommand
{
Action<object> actionDelegate;
public event EventHandler CanExecuteChanged;
public BaseCommand(Action<object> myDelegateAction)
{
actionDelegate = myDelegateAction;
}
public void Execute(object action)
{
actionDelegate(action);
}
public bool CanExecute(object canexecute)
{
return true;
}
public Key KeyGesture { get; set; }
public ModifierKeys ModifierKey { get; set; }
public MouseAction MouseActions { get; set; }
}
Output
In above example, I have bound MyCommand to Button so when user I click on button the MessageBox will appear. I have also bound the same Command with Key and Modifier to KeyBinding and MouseBinding. So when user Press Ctrl+H as well RightMouse Click on the Button the same Messagebox will appear.
Dynamic Object Binding
In WPF 4.0, you can databind dynamic (runtime known) properties. It supports binding to objects which implements IDynamicMetaObjectProvider or inherited from DynamicObject. DynamicObject class provides dynamic behavior at runtime. You can set or get members value by overriding TryGetMember or TrySetMember method.
<Window.Resources>
<local:SimpleDynamicClass x:Key="MyInstance" />
</Window.Resources>
<StackPanel DataContext="{StaticResource MyInstance}">
<Label Content="Enter anything:" />
<TextBox Text="{Binding MyType}" Margin="5" Width="200"
HorizontalAlignment="Left"/>
<Button Content="Click Me!" Click="Button_Click"
HorizontalAlignment="Left"
Height="25" Width="100" Margin="5"/>
<Label Name="ResultLabel" Margin="5" />
</StackPanel>
Code Behind
public class SimpleDynamicClass : DynamicObject
{
public string MyName;
public override bool TryGetMember(GetMemberBinder binder,
out object result)
out object result)
{
result = MyName;
return true;
}
public override bool TrySetMember(SetMemberBinder binder,
object value)
object value)
{
MyName = value.ToString();
return true;
}
}
public partial class NewBindings : Window
{
public NewBindings()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
dynamic MyInstance = FindResource("MyInstance");
ResultLabel.Content = MyInstance.MyType;
}
}
Output
In above example, I have created one class named SimpleDynamicClass derived from DynamicObject and bind its property with TextBox. On Button click I am retrieving the same instance value from resource and showing it in to the label.