dinsdag 8 maart 2011

How to bind on itemssource of other control

Imagine we want to be able to enable/disable a button depending on whether the itemssource of a listbox contains items.  
1.      What we can do is bind the IsEnabled property of the button to the count of the itemssource.  To be able to do that, we need a collection that will warn us when an item has been added or removed to the collection, we would need an observablecollection.
2.      Then when we bind to the count of the itemssource, we need to be able to convert it to a boolean property.  For this we can write a converter.

3.      Then in the code behind we can write some add and remove operations to test our functionality.

So our XAML with the converter would look like this:

<navigation:Page x:Class="SilverlightApplication1.Home"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    Title="Home"
    Style="{StaticResource PageStyle}" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:SilverlightApplication1="clr-namespace:SilverlightApplication1" xmlns:layoutToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit">
    <UserControl.Resources>
        <SilverlightApplication1:CountGreaterThanZeroConverter x:Key="CountGreaterThanZeroConverter"/>
    </UserControl.Resources>
    <StackPanel x:Name="LayoutRoot" Background="White" Width="150">
        <TextBlock Text="{Binding ElementName=MyAutoCompleteBox, Path=SelectedItem, TargetNullValue='No item selected', StringFormat='Selected Item: {0}'}" />
        <ListBox x:Name="ListBox" BorderThickness="0" SelectionMode="Multiple" ItemsSource="{Binding Items}" />

        <Button x:Name="AddButton" Click="AddButton_Click" Content="AddButton" />
        <Button x:Name="RemoveButton" Click="RemoveButton_Click" Content="RemoveButton" />
        <Button x:Name="DisabledButton" Click="RemoveButton_Click" Content="Disabled Button" IsEnabled="{Binding ItemsSource.Count, ElementName=ListBox,Converter={StaticResource CountGreaterThanZeroConverter}}"  />
    </StackPanel>


</navigation:Page>


The converter itself:
    public class CountGreaterThanZeroConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            return (int)value > 0;
        }

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

        #endregion
    }

And last but not lease the code behind with our items property to bind to:

    public partial class Home : Page
    {
        public Home()
        {
            InitializeComponent();
            Items = new ObservableCollection<string>();


            DataContext = this;

        }

        public ObservableCollection<string> Items
        {
            get;
            private set;
        }


        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }


        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            Items.Add(Guid.NewGuid().ToString());
  
        }

        private void RemoveButton_Click(object sender, RoutedEventArgs e)
        {
            Items.RemoveAt(0);
        }
    }


Geen opmerkingen:

Een reactie posten