Tuesday, July 10, 2012

WPF Binding – Element Binding example - Enable Disable Control based on another control property in WPF

Gone are the days for me to work on Azure. 3 weeks back started with WPF. I have been in web technology for last 5 years and now suddenly shifted to windows applications using WPF.
Now struggling with binding, converters and what not. Anyways, I have started to digest simple WPF concepts one of which I am going to discuss here.
I want to bind a controls property “IsEnabled” to another controls property value. As an example, I am taking the textbox control to enable or disable based on the selction of value in drop down. Ohh sorry, combobox!!! (drop down we generally refer in web application!!)
Lets create a simple WPF application, add two controls viz. combobox and textbox. I created a simple class having 2 properties value and text. This class I will use to bind to combo box. The class is as shown –
public class MyItem
    {
        public int Value { get; set; } 

        public string Text { get; set; }
    } 

    public class MyItems : ObservableCollection<MyItem>
    {
    } 



Now I added the namespace of this class in XAML as shown below –
xmlns:vm="clr-namespace:WpfApplication1"
Add this line in <Window> tag.

Now I created MyItems collection in XAML and gave to combo box.

<ComboBox Height="23" HorizontalAlignment="Left" Margin="138,128,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{StaticResource ResourceKey=ItemsCollections}"
                  DisplayMemberPath="Text" SelectedValuePath="Value" />

Alright, to do element binding in WPF, we need create converters. The property of textbox to enable or disable is “IsEnabled” and it expects the value as boolean. The value I am in dropdown are int. So depending on the selection of value in drop down I wil need to send true or false to IsEnabled property of textbox. To do this conversion, lets add the converter class in Converters folder (manually added by right clicking) as shown below –
public class IntToBoolConverter : IValueConverter
    {
       public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is int)
            {
                if (System.Convert.ToInt32(value) == 1)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return value;
            }
        } 

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Add this converter as a resource in XAML –
In windows tag –
xmlns:vc="clr-namespace:WpfApplication1.Converters"
In windows resources -
<vc:IntToBoolConverter x:Key="intToBoolConverter"></vc:IntToBoolConverter> 

The added a textbox  and configured its IsEnabled property in following way –

<TextBox Height="23" HorizontalAlignment="Left" Margin="138,220,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" IsEnabled="{Binding ElementName=comboBox1,Path=SelectedValue,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource ResourceKey=intToBoolConverter}}"/> 

So my final solution structure is as shown below –
Final XAML code is as shown belwo –
<Window x:Class="WpfApplication1.MainWindow"
        xmlns:vm="clr-namespace:WpfApplication1"     
        xmlns:vc="clr-namespace:WpfApplication1.Converters"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <vc:IntToBoolConverter x:Key="intToBoolConverter"></vc:IntToBoolConverter>
        <vm:MyItems x:Key="ItemsCollections">
            <vm:MyItem Value="1" Text="Yes"></vm:MyItem>
            <vm:MyItem Value="2" Text="No"></vm:MyItem>
        </vm:MyItems>
    </Window.Resources>
    <Grid>        
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="138,128,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{StaticResource ResourceKey=ItemsCollections}"
                  DisplayMemberPath="Text" SelectedValuePath="Value" /> 

        <TextBox Height="23" HorizontalAlignment="Left" Margin="138,220,0,0" Name="textBox1" VerticalAlignment="Top" Width="120"  IsEnabled="{Binding ElementName=comboBox1,Path=SelectedValue,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource ResourceKey=intToBoolConverter}}"/>
    </Grid>
</Window>

Now run the application and change the drodown selection. The textbox should get enabled or disable depending on the value selected in combo box.
Cheers…
Happy Programming!!!

2 comments: