【问题标题】:Why MVVM/WPF ComboBox SelectedItem is null in multibinding to other control's Visibility?为什么 MVVM/WPF ComboBox SelectedItem 在多重绑定到其他控件的可见性时为空?
【发布时间】:2015-04-01 14:17:53
【问题描述】:

编辑:我绑定到与组合框绑定的相同属性(SearchType)-> 工作正常。我仍然想知道为什么我在这里描述的第一个解决方案不起作用。

我有

public enum SearchType
{
    NetworkObjects,
    Customers
}

在 ViewModel 构造函数中:

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

在 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>

转换器:

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

在转换方法中,值有 2 个项目和值[1]==null。此外,如果我取消绑定 SelectedItem 是 ViewModel 构造函数中设置的 SearchType.NetworkObjects 。我做错了什么?

【问题讨论】:

  • 什么是SearchTypes,SearchType.NetworkObjects存在于其中吗?另外,您是否遇到异常?你能改用 MultiDataTrigger 吗?
  • 我认为这是一种有效的方法。现在您的控件依赖于视图模型,如果您删除了 ComboBox 并且您的 DataGrid 依赖于它,它将无法编译。此外,它可能在控件初始化过程中显示为 null,然后在渲染后立即设置。
  • @matti 你能发布你的转换器的所有代码吗?我想我可能有答案,但不知道预期的行为是什么
  • 它命中转换器的次数。什么时候应用数据上下文?
  • 有时会发生在我身上。我不确定100%是这样,只是我的经验。但无论如何,很高兴能帮助你^^

标签: wpf xaml mvvm multibinding


【解决方案1】:

我预计您尚未发布的代码中存在问题。我使用提供的代码编写了一个行为非常相似的解决方案,除非我删除了 ComboBox.SelectedItem 绑定,否则不会出现 values[1] == null 的情况。

Here 是工作示例。

【讨论】:

  • 非常感谢。我正在使用带有 ViewModel 类的框架/平台,问题可能就在那里。
  • 正如你所说,问题出在转换器上。测试值的条件应该是在开始(已经在问题中显示)。
【解决方案2】:

问题在于,在我使用的平台设置 DataContext 之前,代码后面的平台 InitializeComponent 被调用。因此,使用未绑定(默认)值调用转换器,在这种情况下,对于 SelectedItem,该值是 null。解决方案是检查值数组,尤其是 values[1],如果值为 null(或 SearchType 以外的任何值),则返回 Bindin.DoNothing。

猜想这通常是一种很好的做法。感谢@Neil 和@NETScape 指出这一点。

   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;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-16
    • 2010-10-24
    • 2012-06-19
    • 2020-09-01
    • 2011-02-24
    • 1970-01-01
    • 2011-11-01
    • 2016-03-25
    相关资源
    最近更新 更多