简体   繁体   中英

Why MVVM/WPF ComboBox SelectedItem is null in multibinding to other control's Visibility?

EDIT : I bound to same property (SearchType) that combobox binds to -> works fine. I still would like to know why my first solution described here does not work.

I have

public enum SearchType
{
    NetworkObjects,
    Customers
}

In ViewModel contructor:

public  SearchViewModel()
{
    SearchType = Panels.SearchType.NetworkObjects;

In xaml:

<UserControl.Resources>
    <xpui:ConvertSearchTypeToVisibility x:Key="searchtypetovisibilityconverter" />
</UserControl.Resources>

<ComboBox
            Name="SearchTypeComboBox"
            ItemsSource="{Binding Path=SearchTypes}"
            SelectedItem="{Binding Path=SearchType, Mode=TwoWay}">
...
<DataGrid.Visibility>
   <MultiBinding Converter="{StaticResource searchtypetovisibilityconverter}">
       <Binding RelativeSource="{RelativeSource Self}" Path="Name"/>
           <Binding ElementName="SearchTypeComboBox" Path="SelectedItem" />
   </MultiBinding>
</DataGrid.Visibility>

Converter:

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    string gridName = (string)values[0];
    SearchType searchType = (SearchType)values[1];

In Convert-method values have 2 items and values[1]==null. Also if I take away the binding SelectedItem is SearchType.NetworkObjects as set in ViewModel constructor. What do I do wrong?

I expect that there is something going wrong in code that you haven't posted. I wrote up a solution with very similar behavior using the provided code and there was no case where values[1] == null unless I removed the ComboBox.SelectedItem binding.

Here is the working sample.

The problem is that in platform InitializeComponent in code behind is called before the DataContext is set by the platform I use. Therefore the Converter is called with the unbound (default) values, which in this case is null for the SelectedItem. The solution is to check the values-array and especially values[1] and return the Bindin.DoNothing if the value is null (or anything but SearchType).

Guess this is good practice in general. Thanks to @Neil and @NETScape to point this out.

   public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values != null && values.Length == 2 && values[0] is string && values[1] is SearchType)
        {
            string gridName = (string)values[0];
            SearchType searchType = (SearchType)values[1];

            if ((gridName == "ObjectSearchResults" && searchType == SearchType.NetworkObjects) ||
                (gridName == "CustomerSearchResults" && searchType == SearchType.Customers))
            {
                return Visibility.Visible;
            }
            return Visibility.Collapsed;
        }
        return Binding.DoNothing;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM