none
Why my MultiBinding does not work? RRS feed

  • Question

  • I am coding a page to select Province/City/County. When one of the ComboBoxs is not select, the next Button is unenabled.

    What's more, some City has no County that the IMultiValueConverter will check if the County items is 0.

    Here is my code:

    XAML:

    <Window x:Class="WpfApp1.MainWindow"
            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:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Window.Resources>
            <local:NotNullConverter x:Key="NotNullConverter"/>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Grid.IsSharedSizeScope="True">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto" SharedSizeGroup="T"></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock>Province</TextBlock>
                    <ComboBox x:Name="A" Grid.Column="1">
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                    </ComboBox>
                </Grid>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto" SharedSizeGroup="T"></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock>City</TextBlock>
                    <ComboBox x:Name="B" Grid.Column="1">
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                    </ComboBox>
                </Grid>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto" SharedSizeGroup="T"></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock>County</TextBlock>
                    <ComboBox x:Name="C" Grid.Column="1">
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                        <ComboBoxItem>123</ComboBoxItem>
                    </ComboBox>
                </Grid>
            </StackPanel>
            <Button Grid.Row="1">
                <Button.IsEnabled>
                    <MultiBinding Converter="{StaticResource NotNullConverter}">
                        <Binding ElementName="A" />
                        <Binding ElementName="B" />
                        <Binding ElementName="C" />
                    </MultiBinding>
                </Button.IsEnabled>
            </Button>
        </Grid>
    </Window>

    Code-behind:

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace WpfApp1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
        }
        public class NotNullConverter : IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
                foreach (object o in values)
                {
                    if (o == DependencyProperty.UnsetValue)
                    {
                        return false;
                    }
                    else {
                        ComboBox CB = o as ComboBox;
                        if (CB.Items.Count != 0)
                        {
                            if (CB.SelectedItem == null)
                            {
                                return false;
                            }
                        }
                    }
                }
                return true;
            }

            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }

    Why it can not bind sucessfully and how should I bind this?

    Thank you.

    Saturday, August 17, 2019 4:26 AM

Answers

  • Hi,
    your MultiConvertes doesn't work because the Elements "A", "B" an "C" doesn't change. Only the SelecteItem property changes. You can solve your problem with the following code:

    XAML:

        <Button Grid.Row="1">
          <Button.IsEnabled>
            <MultiBinding Converter="{StaticResource NotNullConverter}">
              <Binding ElementName="A" Path="SelectedItem" />
              <Binding ElementName="B" Path="SelectedItem" />
              <Binding ElementName="C" Path="SelectedItem" />
            </MultiBinding>
          </Button.IsEnabled>
        </Button>

    Converter:

      public class NotNullConverter : IMultiValueConverter
      {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
          foreach (object o in values) if (o == null) return false;
          return true;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Saturday, August 17, 2019 6:16 PM

All replies

  • Hi,
    your MultiConvertes doesn't work because the Elements "A", "B" an "C" doesn't change. Only the SelecteItem property changes. You can solve your problem with the following code:

    XAML:

        <Button Grid.Row="1">
          <Button.IsEnabled>
            <MultiBinding Converter="{StaticResource NotNullConverter}">
              <Binding ElementName="A" Path="SelectedItem" />
              <Binding ElementName="B" Path="SelectedItem" />
              <Binding ElementName="C" Path="SelectedItem" />
            </MultiBinding>
          </Button.IsEnabled>
        </Button>

    Converter:

      public class NotNullConverter : IMultiValueConverter
      {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
          foreach (object o in values) if (o == null) return false;
          return true;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Saturday, August 17, 2019 6:16 PM
  • Hi,
    your MultiConvertes doesn't work because the Elements "A", "B" an "C" doesn't change. Only the SelecteItem property changes. You can solve your problem with the following code:

    XAML:

        <Button Grid.Row="1">
          <Button.IsEnabled>
            <MultiBinding Converter="{StaticResource NotNullConverter}">
              <Binding ElementName="A" Path="SelectedItem" />
              <Binding ElementName="B" Path="SelectedItem" />
              <Binding ElementName="C" Path="SelectedItem" />
            </MultiBinding>
          </Button.IsEnabled>
        </Button>

    Converter:

      public class NotNullConverter : IMultiValueConverter
      {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
          foreach (object o in values) if (o == null) return false;
          return true;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Thank you ,it works.
    Sunday, August 18, 2019 12:57 PM