Execute Silverlight 4 Command on Load - silverlight

How do you implement a Silverlight 4 command to execute when the user control loads instead of being mapped to an explicit button click?

Or simply add a trigger in xaml for your UserControl:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<si:InvokeDataCommand Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>

Create a DependencyProperty of type ICommand:-
#region public ICommand LoadedCommand
public ICommand LoadedCommand
{
get { return GetValue(LoadedCommandProperty) as ICommand; }
set { SetValue(LoadedCommandProperty, value); }
}
public static readonly DependencyProperty LoadedCommandProperty =
DependencyProperty.Register(
"LoadedCommand",
typeof(ICommand),
typeof(MainPage),
new PropertyMetadata(null));
#endregion public ICommand LoadedCommand
Also add a something to act as the command parameter:-
#region public object LoadedCommandParameter
public object LoadedCommandParameter
{
get { return GetValue(LoadedCommandParameterProperty) as object; }
set { SetValue(LoadedCommandParameterProperty, value); }
}
public static readonly DependencyProperty LoadedCommandParameterProperty =
DependencyProperty.Register(
"LoadedCommandParameter",
typeof(object),
typeof(MainPage),
new PropertyMetadata(null));
#endregion public object LoadedCommandParameter
Now set up its execution like this:-
public UserControl1()
{
InitializeComponent();
Loaded += UserControl1_Loaded;
}
void UserControl1_Loaded(object sender, RoutedEventArgs e)
{
if (LoadedCommand != null && LoadedCommand.CanExecute(LoadedCommandParameter))
{
LoadedCommand.Execute(LoadedCommandParameter);
}
}
Now if your ViewModel (has a command called StartStuff) then:-
<UserControl1 LoadedCommand="{Binding StartStuff}" .... >

Thats a load of code. The concise version without the code behind
public class LoadedBehaviour
{
public static ICommand GetLoadedCommand(DependencyObject dependencyObject)
{
return (ICommand)dependencyObject.GetValue(LoadedCommandProperty);
}
public static void SetLoadedCommand(DependencyObject dependencyObject, ICommand value)
{
dependencyObject.SetValue(LoadedCommandProperty, value);
}
public static Action GetLoadedCommandExecutor(DependencyObject dependencyObject)
{
return (Action)dependencyObject.GetValue(LoadedCommandExecutorProperty);
}
public static void SetLoadedCommandExecutor(DependencyObject dependencyObject, Action value)
{
dependencyObject.SetValue(LoadedCommandExecutorProperty, value);
}
public static readonly DependencyProperty LoadedCommandProperty = DependencyProperty.Register("LoadedCommand", typeof(ICommand), typeof(FrameworkElement), new PropertyMetadata(OnPropertyChanged));
public static readonly DependencyProperty LoadedCommandExecutorProperty = DependencyProperty.Register("LoadedCommandExecutor", typeof(Action), typeof(FrameworkElement), new PropertyMetadata(OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is FrameworkElement))
{
throw new ArgumentException("Loaded command can only be used on FrameworkElements");
var executor = GetLoadedCommandExecutor(d);
if(executor == null)
{
executor = () =>
{
var command = GetLoadedCommand(d);
command.Execute(e);
};
SetLoadedCommandExecutor(d, executor);
((FrameworkElement)d).Loaded += (obj, args) => executor();
}
}
}

Related

Handling Mouse Events in MVVM in WPF

I am Using MVVM with WPF. i am halted in a way, i want your views about this. i am firing Mouse Events using MouseBehaviour.cs class , Is there any other way to handle Mouse Events in MVVM WPF
using System.Windows;
using System.Windows.Input;
namespace Lovatts.MouseBehaviours
{
public class MouseBehaviour
{
#region MouseUp
public static readonly DependencyProperty MouseUpCommandProperty =
DependencyProperty.RegisterAttached("MouseUpCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseUpCommandChanged)));
private static void MouseUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseUp += element_MouseUp;
}
static void element_MouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseUpCommand(element);
command.Execute(e);
}
public static void SetMouseUpCommand(UIElement element, ICommand value)
{
element.SetValue(MouseUpCommandProperty, value);
}
public static ICommand GetMouseUpCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseUpCommandProperty);
}
#endregion
#region MouseDown
public static readonly DependencyProperty MouseDownCommandProperty =
DependencyProperty.RegisterAttached("MouseDownCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseDownCommandChanged)));
private static void MouseDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseDown += element_MouseDown;
}
static void element_MouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseDownCommand(element);
command.Execute(e);
}
public static void SetMouseDownCommand(UIElement element, ICommand value)
{
element.SetValue(MouseDownCommandProperty, value);
}
public static ICommand GetMouseDownCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseDownCommandProperty);
}
#endregion
#region MouseLeave
public static readonly DependencyProperty MouseLeaveCommandProperty =
DependencyProperty.RegisterAttached("MouseLeaveCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeaveCommandChanged)));
private static void MouseLeaveCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseLeave += new MouseEventHandler(element_MouseLeave);
}
static void element_MouseLeave(object sender, MouseEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseLeaveCommand(element);
command.Execute(e);
}
public static void SetMouseLeaveCommand(UIElement element, ICommand value)
{
element.SetValue(MouseLeaveCommandProperty, value);
}
public static ICommand GetMouseLeaveCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseLeaveCommandProperty);
}
#endregion
#region MouseLeftButtonDown
public static readonly DependencyProperty MouseLeftButtonDownCommandProperty =
DependencyProperty.RegisterAttached("MouseLeftButtonDownCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeftButtonDownCommandChanged)));
private static void MouseLeftButtonDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseLeftButtonDown += element_MouseLeftButtonDown;
}
static void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseLeftButtonDownCommand(element);
command.Execute(e);
}
public static void SetMouseLeftButtonDownCommand(UIElement element, ICommand value)
{
element.SetValue(MouseLeftButtonDownCommandProperty, value);
}
public static ICommand GetMouseLeftButtonDownCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseLeftButtonDownCommandProperty);
}
#endregion
#region MouseLeftButtonUp
public static readonly DependencyProperty MouseLeftButtonUpCommandProperty =
DependencyProperty.RegisterAttached("MouseLeftButtonUpCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseLeftButtonUpCommandChanged)));
private static void MouseLeftButtonUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseLeftButtonUp += element_MouseLeftButtonUp;
}
static void element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseLeftButtonUpCommand(element);
command.Execute(e);
}
public static void SetMouseLeftButtonUpCommand(UIElement element, ICommand value)
{
element.SetValue(MouseLeftButtonUpCommandProperty, value);
}
public static ICommand GetMouseLeftButtonUpCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseLeftButtonUpCommandProperty);
}
#endregion
#region MouseMove
public static readonly DependencyProperty MouseMoveCommandProperty =
DependencyProperty.RegisterAttached("MouseMoveCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseMoveCommandChanged)));
private static void MouseMoveCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseMove += new MouseEventHandler(element_MouseMove);
}
static void element_MouseMove(object sender, MouseEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseMoveCommand(element);
command.Execute(e);
}
public static void SetMouseMoveCommand(UIElement element, ICommand value)
{
element.SetValue(MouseMoveCommandProperty, value);
}
public static ICommand GetMouseMoveCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseMoveCommandProperty);
}
#endregion
#region MouseRightButtonDown
public static readonly DependencyProperty MouseRightButtonDownCommandProperty =
DependencyProperty.RegisterAttached("MouseRightButtonDownCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseRightButtonDownCommandChanged)));
private static void MouseRightButtonDownCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseRightButtonDown += element_MouseRightButtonDown;
}
static void element_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseRightButtonDownCommand(element);
command.Execute(e);
}
public static void SetMouseRightButtonDownCommand(UIElement element, ICommand value)
{
element.SetValue(MouseRightButtonDownCommandProperty, value);
}
public static ICommand GetMouseRightButtonDownCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseRightButtonDownCommandProperty);
}
#endregion
#region MouseRightButtonUp
public static readonly DependencyProperty MouseRightButtonUpCommandProperty =
DependencyProperty.RegisterAttached("MouseRightButtonUpCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseRightButtonUpCommandChanged)));
private static void MouseRightButtonUpCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseRightButtonUp += element_MouseRightButtonUp;
}
static void element_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseRightButtonUpCommand(element);
command.Execute(e);
}
public static void SetMouseRightButtonUpCommand(UIElement element, ICommand value)
{
element.SetValue(MouseRightButtonUpCommandProperty, value);
}
public static ICommand GetMouseRightButtonUpCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseRightButtonUpCommandProperty);
}
#endregion
#region MouseWheel
public static readonly DependencyProperty MouseWheelCommandProperty =
DependencyProperty.RegisterAttached("MouseWheelCommand", typeof(ICommand), typeof(MouseBehaviour), new FrameworkPropertyMetadata(new PropertyChangedCallback(MouseWheelCommandChanged)));
private static void MouseWheelCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
element.MouseWheel += new MouseWheelEventHandler(element_MouseWheel);
}
static void element_MouseWheel(object sender, MouseWheelEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
ICommand command = GetMouseWheelCommand(element);
command.Execute(e);
}
public static void SetMouseWheelCommand(UIElement element, ICommand value)
{
element.SetValue(MouseWheelCommandProperty, value);
}
public static ICommand GetMouseWheelCommand(UIElement element)
{
return (ICommand)element.GetValue(MouseWheelCommandProperty);
}
#endregion
}
}
Here is my Xaml Code
<Window x:Class="Lovatts.MouseBehaviours.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:MouseBehaviours="clr-namespace:Lovatts.MouseBehaviours" x:Name="RibbonWindow"
Width="640" Height="480" DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid>
<Rectangle Width="100" Height="100" Fill="Blue" MouseBehaviours:MouseBehaviour.MouseUpCommand="{Binding MouseUpCommand}">
</Rectangle>
<Rectangle Width="100" Height="100" x:Name="Rectangle" Fill="Red" MouseBehaviours:MouseBehaviour.MouseUpCommand="{Binding MouseUpCommand}" Margin="75,109,457,241">
</Rectangle>
</Grid>
</Window>
MainViewModel.cs
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Windows;
namespace MouseBehaviours.ViewModel
{
public class MainViewModel : ViewModelBase
{
private RelayCommand _mouseUpCommand;
public RelayCommand MouseUpCommand
{
get
{
if (_mouseUpCommand == null) return _mouseUpCommand = new RelayCommand(param => ExecuteMouseUp((MouseEventArgs)param));
return _mouseUpCommand;
}
set { _mouseUpCommand = value; }
}
private void ExecuteMouseUp(MouseEventArgs e)
{
Console.WriteLine("Mouse Up : " + e.GetPosition((IInputElement)e.Source));
}
}
public class RelayCommand : ICommand
{
#region Fields
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
private string _displayText;
public static List<string> Log = new List<string>();
private Action<object> action;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
: this(execute, canExecute, "")
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute, string displayText)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
_displayText = displayText;
}
public string DisplayText
{
get { return _displayText; }
set { _displayText = value; }
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
//class MainViewModel
//{
//}
}
Instead of writing you own behavior and calling commands from it, you can leverage the EventTriggers and Interactivity to bind the event action to the command.
here is simple example of doing it
http://www.c-sharpcorner.com/Blogs/11789/example-of-eventtrigger-in-mvvm-application.aspx
as described in the example if you want to fire command on MouseUp event on your rectangle you can just do:
<Rectangle >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseUp">
<i:InvokeCommandAction Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle >
#harjeet you need to use the below structure for Image MouseUp i.e instead of using "Image" try to use "Hyperlink command property" in TextBlock:
<TextBlock Panel.ZIndex="990"
Canvas.Right="30"
Canvas.Left="498"
Canvas.Top="4">
<Hyperlink TextDecorations="None"
Command="{Binding CloseLoginSettingPopup}">
<Image Cursor="Hand"
x:Name="Pop2"
Source="/img/close1.png"
Height="40"
Width="40"
Panel.ZIndex="990"
Canvas.Right="30"
Canvas.Left="498"
Canvas.Top="4" />
</Hyperlink>
</TextBlock>
https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.mouseaction
<Rectangle>
<Rectangle.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding MyCommand}" />
</Rectangle.InputBindings>
</Rectangle>

WPF: Passing main form property to user control

I have set up my own user control which contains two ComboBoxes, each ComboBox item source is bound to a DependencyProperty. The issue I am having is passing a property from the form that uses my user control to the user control.
Below is my user control:
public static readonly DependencyProperty ListOneProperty = DependencyProperty.Register
("ListOne", typeof(List<int>), typeof(LinkedComboBox), new PropertyMetadata(new List<int>()));
public List<int> ListOne
{
get { return (List<int>)GetValue(ListOneProperty); }
set { SetValue(ListOneProperty, value); }
}
public static readonly DependencyProperty ListTwoProperty = DependencyProperty.Register
("ListTwo", typeof(List<string>), typeof(LinkedComboBox), new PropertyMetadata(new List<string>()));
public List<string> ListTwo
{
get { return (List<string>)GetValue(ListTwoProperty); }
set { SetValue(ListTwoProperty, value); }
}
public LinkedComboBox()
{
InitializeComponent();
FillListOne();
}
And below is my MainWindow xaml:
<control:LinkedComboBox x:Name="LinkedBox" ListTwo="{Binding MyList}"/>
And MainWindow.xaml.cs:
static List<string> _myList = new List<string>{"abc","efg"};
public List<string> MyList
{
get { return _myList; }
set { _myList = value; }
}
public MainWindow()
{
InitializeComponent();
}
What do I need to get the User Control to accept a binding from the Main Window?
Everything is fine except that you need a PropertyChangedCallback to handle your property.
Here is a simple example
public static readonly DependencyProperty ListTwoProperty = DependencyProperty.Register
("ListTwo", typeof(List<string>), typeof(LinkedComboBox), new PropertyMetadata(new List<string>(), new PropertyChangedCallback(Changed)));
private static void Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//e.NewValue here is your MyList in MainWindow.
}

Can not set SelectionChangedCommand.Command

I try to use this xaml, to apply an event to command binding:
<telerik:RadGridView x:Name="xRadGridView"
prismcommands:SelectionChangedCommand.Command="{Binding SelectPersonCommand}"
ItemsSource="{Binding GridItems, Mode=TwoWay}">
</telerik:RadGridView>
I get the error:
'SelectionChangedCommand.Command' property is read-only and cannot be
set from markup.
I can bind to prismcommands:RowEditEndedCommand.Command with no problem.
Is there any chance to bind to SelectionChangedCommand.Command?
I use the same PrismCommands in a Silverlight project and it works there.
namespace RadEventToCommand.WPF.PrismCommands
{
public class RowEditEndedCommandBehavior : CommandBehaviorBase<RadGridView>
{
public RowEditEndedCommandBehavior(RadGridView gridView)
: base(gridView)
{
gridView.RowEditEnded +=new EventHandler<GridViewRowEditEndedEventArgs>(gridView_RowEditEnded);
}
void gridView_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
{
CommandParameter = e;
ExecuteCommand();
}
}
}
--
namespace RadEventToCommand.WPF.PrismCommands
{
public static class SelectionChangedCommand
{
private static readonly DependencyProperty SelectionChangedCommandBehaviorProperty
= DependencyProperty.RegisterAttached(
"SelectionChangedCommandBehavior",
typeof(SelectionChangedCommandBehavior),
typeof(SelectionChangedCommand),
null);
public static readonly DependencyProperty CommandProperty
= DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(SelectionChangedCommand),
new PropertyMetadata(OnSetCommandCallback));
public static readonly DependencyProperty CommandParameterProperty
= DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(SelectionChangedCommand),
new PropertyMetadata(OnSetCommandParameterCallback));
public static ICommand GetCommand(RadGridView gridView)
{
return gridView.GetValue(CommandProperty) as ICommand;
}
public static void SetCommandParameter(RadGridView gridView, object parameter)
{
gridView.SetValue(CommandParameterProperty, parameter);
}
public static object GetCommandParameter(RadGridView gridView)
{
return gridView.GetValue(CommandParameterProperty);
}
private static void OnSetCommandCallback
(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
RadGridView gridView = dependencyObject as RadGridView;
if (gridView != null)
{
SelectionChangedCommandBehavior behavior = GetOrCreateBehavior(gridView);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback
(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
RadGridView gridView = dependencyObject as RadGridView;
if (gridView != null)
{
SelectionChangedCommandBehavior behavior = GetOrCreateBehavior(gridView);
behavior.CommandParameter = e.NewValue;
}
}
private static SelectionChangedCommandBehavior GetOrCreateBehavior(RadGridView gridView)
{
SelectionChangedCommandBehavior behavior =
gridView.GetValue(SelectionChangedCommandBehaviorProperty) as SelectionChangedCommandBehavior;
if (behavior == null)
{
behavior = new SelectionChangedCommandBehavior(gridView);
gridView.SetValue(SelectionChangedCommandBehaviorProperty, behavior);
}
return behavior;
}
}
}
--
namespace RadEventToCommand.WPF.PrismCommands
{
public class RowEditEndedCommandBehavior : CommandBehaviorBase<RadGridView>
{
public RowEditEndedCommandBehavior(RadGridView gridView)
: base(gridView)
{
gridView.RowEditEnded +=new EventHandler<GridViewRowEditEndedEventArgs>(gridView_RowEditEnded);
}
void gridView_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
{
CommandParameter = e;
ExecuteCommand();
}
}
}
--
namespace RadEventToCommand.WPF.PrismCommands
{
public static class RowEditEndedCommand
{
private static DependencyProperty RowEditEndedCommandBehaviorProperty
= DependencyProperty.RegisterAttached(
"RowEditEndedCommandBehavior",
typeof(RowEditEndedCommandBehavior),
typeof(RowEditEndedCommand),
null);
public static DependencyProperty CommandProperty
= DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(RowEditEndedCommand),
new PropertyMetadata(OnSetCommandCallback));
public static DependencyProperty CommandParameterProperty
= DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(RowEditEndedCommand),
new PropertyMetadata(OnSetCommandParameterCallback));
public static ICommand GetCommand(RadGridView gridView)
{
return gridView.GetValue(CommandProperty) as ICommand;
}
public static void SetCommand(RadGridView gridView, object parameter)
{
gridView.SetValue(CommandProperty, parameter);
}
public static void SetCommandParameter(RadGridView gridView, object parameter)
{
gridView.SetValue(CommandParameterProperty, parameter);
}
public static object GetCommandParameter(RadGridView gridView)
{
return gridView.GetValue(CommandParameterProperty);
}
private static void OnSetCommandCallback
(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
RadGridView gridView = dependencyObject as RadGridView;
if (gridView != null)
{
RowEditEndedCommandBehavior behavior = GetOrCreateBehavior(gridView);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback
(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
RadGridView gridView = dependencyObject as RadGridView;
if (gridView != null)
{
RowEditEndedCommandBehavior behavior = GetOrCreateBehavior(gridView);
behavior.CommandParameter = e.NewValue;
}
}
private static RowEditEndedCommandBehavior GetOrCreateBehavior(RadGridView gridView)
{
RowEditEndedCommandBehavior behavior =
gridView.GetValue(RowEditEndedCommandBehaviorProperty) as RowEditEndedCommandBehavior;
if (behavior == null)
{
behavior = new RowEditEndedCommandBehavior(gridView);
gridView.SetValue(RowEditEndedCommandBehaviorProperty, behavior);
}
return behavior;
}
}
}
I had the source for the behavior copied over from a Silverlight project. It worked there. For some reason in WPF I need the additional method in SelectionChangedCommand
public static void SetCommand(RadGridView gridView, object parameter)
{
gridView.SetValue(CommandProperty, parameter);
}
I copied the code over to check if I could use a common codebase for Silverlight and WPF.
For the RadGridView, we are using the Interaction Triggers. The below code works for us.
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>

MVVM DependencyProperty doesn't update when RaisePropertyChanged

I have usercontrol, and there is a DependencyProperty defined in it.
#region ImageUri
public static readonly DependencyProperty ImageUriProperty = DependencyProperty.Register(
"ImageUri",
typeof(string),
typeof(ScrollableCanvas),
new PropertyMetadata(new PropertyChangedCallback(ImageUriPropertyChangedCallback)));
private static void ImageUriPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
ScrollableCanvas main = sender as ScrollableCanvas;
if (main != null)
{
main.ImageUri = (string)e.NewValue;
}
}
public string ImageUri
{
get
{
return (string)GetValue(ImageUriProperty);
}
set
{
SetValue(ImageUriProperty, value);
UpdateImage();
}
}
#endregion
In the Xaml, I bind a value to it like this
<my:ScrollableCanvas Name="scrollableCanvas1" ImageUri="{Binding Path=LayerImage}" />
when I update the LayerImage in the viewmodel, the ImageUri property does not update.
Can some help on this? Thanks.
BTW: The value is updated when I set the LayerImage in the constructor of the viewmodel.
You shouldn't include your UpdateImage call in your setter, but rather in the property changed callback.
public static readonly DependencyProperty ImageUriProperty = DependencyProperty.Register(
"ImageUri",
typeof(string),
typeof(ScrollableCanvas),
new PropertyMetadata(new PropertyChangedCallback(ImageUriPropertyChangedCallback)));
private static void ImageUriPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
ScrollableCanvas main = sender as ScrollableCanvas;
if (main != null)
{
// Since ImageUri has already been called at this point, you can just update your image here...
main.UpdateImage();
}
}
public string ImageUri
{
get
{
return (string)GetValue(ImageUriProperty);
}
set
{
SetValue(ImageUriProperty, value);
}
}

Logically combine dependency properties

I'm using C# 4.0 and have created a DependencyObject MyView.
In MyView, I have two DependencyProperties, PropA and PropB, both are booleans.
I want a third DependencyProperty, PropC, also a bool, and simply put, should always give me (PropA || PropB).
What is the best way to accomplish this?
I was also thinking of making PropC a readonly DependencyProperty, but have read about issues with binding to readonly dp's (WPF ReadOnly Dependency Properties using MVVM)
You can use the Dependency Property changed callback for PropA and PropB to set the value for PropC (don't use the CLR property wrapper for the Dependency Properties as they are never guaranteed to be called).
If you have these three DP's
public static readonly DependencyProperty PropAProperty =
DependencyProperty.Register("PropA",
typeof(bool),
typeof(MyView),
new PropertyMetadata(false, PropAPropertyChanged));
public static readonly DependencyProperty PropBProperty =
DependencyProperty.Register("PropB",
typeof(bool),
typeof(MyView),
new PropertyMetadata(false, PropBPropertyChanged));
public static readonly DependencyProperty PropCProperty =
DependencyProperty.Register("PropC",
typeof(bool),
typeof(MyView),
new PropertyMetadata(false));
public bool PropA
{
get { return (bool)this.GetValue(PropAProperty); }
set { this.SetValue(PropAProperty, value); }
}
public bool PropB
{
get { return (bool)this.GetValue(PropBProperty); }
set { this.SetValue(PropBProperty, value); }
}
public bool PropC
{
get { return (bool)this.GetValue(PropCProperty); }
set { this.SetValue(PropCProperty, value); }
}
you can use the property changed callback like this
private static void PropAPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
MyView myView = source as MyView;
myView.OnPropChanged();
}
private static void PropBPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
MyView myView = source as MyView;
myView.OnPropChanged();
}
public void OnPropChanged()
{
PropC = PropA || PropB;
}
This way, you'll always update the value of PropC everytime PropA or PropB changes
Also, PropC doesn't need to be a DP, it can be a normal CLR property if you implement INotifyPropertyChanged. Then the implementation can look like this instead
public void OnPropChanged()
{
OnPropertyChanged("PropC");
}
public bool PropC
{
get
{
return PropA || PropB;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
You could also bind PropC to PropA and PropB with a MultiBinding. Let me know if you want an example of this as well
The linked web page is for an unusual situation, a "push" binding. That is, a one-way-to-source binding was attempted on the read-only property, not on another property trying to bind to it. By contrast, if you want your property to be bindable to other properties using a one-way binding expression on the other property, then you can use a read-only dependency property without any issues.
Edit:
Here is an example:
<Grid>
<Grid.Resources>
<local:MyObject x:Key="myObject" PropertyA="True" PropertyB="False"/>
</Grid.Resources>
<StackPanel DataContext="{StaticResource myObject}">
<CheckBox IsChecked="{Binding PropertyA}" Content="PropertyA"/>
<CheckBox IsChecked="{Binding PropertyB}" Content="PropertyB"/>
<CheckBox IsChecked="{Binding PropertyC, Mode=OneWay}" IsEnabled="False" Content="PropertyC"/>
</StackPanel>
</Grid>
and the dependency properties, one of which is read-only:
public class MyObject : DependencyObject
{
public bool PropertyA
{
get { return (bool)GetValue(PropertyAProperty); }
set { SetValue(PropertyAProperty, value); }
}
public static readonly DependencyProperty PropertyAProperty =
DependencyProperty.Register("PropertyA", typeof(bool), typeof(MyObject), new UIPropertyMetadata(false, OnPropertyAOrBChanged));
public bool PropertyB
{
get { return (bool)GetValue(PropertyBProperty); }
set { SetValue(PropertyBProperty, value); }
}
public static readonly DependencyProperty PropertyBProperty =
DependencyProperty.Register("PropertyB", typeof(bool), typeof(MyObject), new UIPropertyMetadata(false, OnPropertyAOrBChanged));
public bool PropertyC
{
get { return (bool)GetValue(PropertyCProperty); }
set { SetValue(PropertyCPropertyKey, value); }
}
private static readonly DependencyPropertyKey PropertyCPropertyKey =
DependencyProperty.RegisterReadOnly("PropertyC", typeof(bool), typeof(MyObject), new UIPropertyMetadata());
public static readonly DependencyProperty PropertyCProperty = PropertyCPropertyKey.DependencyProperty;
private static void OnPropertyAOrBChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var myObject = d as MyObject;
myObject.PropertyC = myObject.PropertyA || myObject.PropertyB;
}
}

Resources