|
I'm working on an WPF MVVM application. The data entry screen has to have all it's fields disabled until the user clicks "Add" or "Edit", and also the fields cannot become enabled if the user does not have rights to that field.
So, I would like to bind all IsEnabled properties in the XAML to a single method on the ViewModel. I would need to pass in a string value which is the 'key' of the field. Then in the VM would use the key to check the rights. The method would be something like
public bool CanEnableField(string Key)
{
}
A converter would probably not work because that class won't know about the VM and the form's mode (Add/Edit).
I could bind each field's IsEnabled to individual properties on the VM and handle all this in the getter, but that would be a lot of properties in the VM.
Anyone have any thoughts on how to do this?
If it's not broken, fix it until it is
|
|
|
|
|
The best way is to have a bool Property in your VM, to which you caan bind the IsEnabled property of the relevant controls like this:-
VM:
public bool CanEnableField(string Key)
{
}
public bool EnableControls
{
get
{
return enableControls;
}
set
{
if (enableControls != value)
{
enableControls = value;
OnPropertyChanged("EnableControls");
}
}
}
View:
<Label Grid.Row="2" Content="Name : " HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="2,2,2,7" />
<TextBox Grid.Column="1" Grid.Row="2" Margin="2" IsEnabled="{Binding Path=EnableControls}" Text="{Binding Path=SelectedCustomer.Name, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
If you're using .NET 4.0 or 4.5, you can combine a single property with a dynamic object to achieve this:
public interface ICanEnableField
{
bool CanEnableField(string key);
}
public sealed class CanEnableFieldHelper : DynamicObject
{
private readonly ICanEnableField _owner;
public CanEnableFieldHelper(ICanEnableField owner)
{
_owner = owner;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _owner.CanEnableField(binder.Name);
return true;
}
}
public class YourViewModel : ICanEnableField
{
private readonly CanEnableFieldHelper _helper;
public YourViewModel()
{
_helper = new CanEnableFieldHelper(this);
}
public dynamic CanEnable
{
get { return _helper; }
}
public bool CanEnableField(string key)
{
...
}
}
In you XAML, you can then bind to CanEnable.Key , which will return the result of calling CanEnableField("Key") :
<TextBox IsEnabled="{Binding Path=CanEnable.Field1}" ... />
When you need to change the state, you just need to raise the PropertyChanged event for the CanEnable property.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, I'll take a look at it
If it's not broken, fix it until it is
|
|
|
|
|
This worked perfect. Thanks!
If it's not broken, fix it until it is
|
|
|
|