You can dynamically enable and disable fields in the Data Standard dialog based on values entered by the user. For instance, if you have a combo box where the user selects a value, you can automatically enable new fields based on the selected value.
In this example, we create new fields and group them by a GroupBox. The GroupBox content is enabled or disabled based on the text entered into a TextBox project.
Here is how it might look in the dialog:
To simplify the steps, we group our fields in the code. This way, we can disable or enable the complete group in case our rule returns false or true. So, first, create a GroupBox which contains optional fields. Here is the code:
<GroupBox Header="Advanced project information" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Top" IsEnabled="{Binding Source={StaticResource DataStandardModelResource}, Path=IsCustomControlEnabled}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="120"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Label Content="Project number" Grid.Column="0" Grid.Row="0" /> <TextBox Text="{Binding Prop[ProjectNumber].Value}" Grid.Column="1" Grid.Row="0"/> <Label Content="Cost Center" Grid.Column="0" Grid.Row="1" /> <TextBox Text="{Binding Prop[Costcenter].Value}" Grid.Column="1" Grid.Row="1"/> <Label Content="Delivery date" Grid.Column="0" Grid.Row="2" /> <TextBox Text="{Binding Prop[DeliveryDate].Value}" Grid.Column="1" Grid.Row="2"/> </Grid> </GroupBox>
The GroupBox, like most of all other controls, exposes the property IsEnabled, which controls whether the control and its children are enabled for use or not. To dynamically enable or disable this control and its children, we bound the IsEnabled attribute to the property of a custom view model (custom DLL), created in the next section.
The logic if and when the control should be disable or enabled is then written into our custom code.
Here is the code of our DLL:
namespace DynEnableDisable { public class DataStandardModel : CustomerViewModelBase { public DataStandardModel() { if(!base.IsInDesignMode) base.Properties["Project"].PropertyChanged += DataStandardModel_ProjectValueChanged; } void myViewModel_ProjectValueChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "Value") { if (Properties["Project"].Value.ToString().ToLower().Contains("advanced")) IsCustomControlEnabled = true; else IsCustomControlEnabled = false; } } private bool _IsCustomControlEnabled = false; public bool IsCustomControlEnabled { get { return _IsCustomControlEnabled; } private set { _IsCustomControlEnabled = value; OnPropertyChanged("IsCustomControlEnabled"); } } } }
In the constructor we overload the PropertyChanged event with our own event handler. This way, we get notified every time the user applies changes to the Project property. To avoid that, the Visual Studio generates an error as it tries to render the XAML file. The if statement checks whether we are InDesignMode or not. In the event handler, (myViewModel_PropertyValueChanged), the first if statement checks whether the event was called by a value change or another type of change. In case of a value change, we check what the user has inserted in the TextBox and if the value "advanced" has been typed by the user, then we set the property IsCustomControlEnabled to true.
Compile the DLL and place it into the add-ins folder for Data Standard.
Declare in your XAML file the existance of our new DLL. In the header of the XAML file, define a namespace alias for your DLL:
<prop:dsWindow xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prop="clr-namespace:dataStandard.UI.View;assembly=dataStandard.UI" xmlns:myvm="clr-namespace:DynEnableDisable;assembly=DynEnableDisable" x:Name="MainWindow" Title="{Binding PathAndFileNameHandler.FileName}" WindowStyle="ToolWindow" ShowInTaskbar="False" Topmost="True" SizeToContent="WidthAndHeight">
The xmlns:myvn is the alias for our DLL. Now let's define our class as a resource in order to use it later in the XAML:
<prop:dsWindow.Resources> <myvm:DataStandardModel x:Name="DataStandardModelResource"> </prop:dsWindow.Resources>
So, we create an instance of the class DataStandardModel out of the myvm namespace (our DLL) and give the alias myViewModelResource, which will be useful later. In the first step we already bound the IsEnable property of the GroupBox to the IsCustomControlEnabled via the resource DataStandardModelResource just defined a few rows above.
Now when the user edits the project property, our event gets notified, our custom logic works and decides whether to set the IsCustomControlEnable to true or false. Based on this value, the GroupBox is enabled or disabled.