【问题标题】:Multibinding expression always showing DependencyProperty.UnsetValue in it's multiconverter多绑定表达式总是在它的多转换器中显示 DependencyProperty.UnsetValue
【发布时间】:2020-10-06 20:35:01
【问题描述】:
<ContextMenuService.ContextMenu>
   <ContextMenu>
     <MenuItem IsCheckable="False" x:Name="MnuSendToFolder" Header="{Binding Path=SendToFolder, 
          Source={StaticResource LRWpf}}"   Command="{Binding SendToFolderCommand}" >
       <MenuItem.IsEnabled>
          <MultiBinding Converter="{StaticResource VisibilityConverter}">
               <Binding ElementName="QuantChartWindow" Path="DataContext.IsSurveyModeOn" />
               <Binding ElementName="QuantChartWindow" Path="DataContext.CommonProgressVisibility" />
          </MultiBinding> 
        </MenuItem.IsEnabled>
     </MenuItem>
   </ContextMenu>
</ContextMenuService.ContextMenu>

这里,QuantChartWindow 是主 UserControl 的名称,其数据上下文设置为该控件的视图模型。 IsSurveyModeOn 和 CommonProgressVisibility 是视图模型的公共属性。 在 multiconverter 的 Convert 函数中,这两个值总是以 UnsetValue 的形式出现。

public class VisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if(values!=null && values.Length==2)
        {
            Visibility visvalue = (Visibility)values[1];
            bool isSurveyMode = (bool)values[0];
            if (visvalue == Visibility.Hidden || visvalue == Visibility.Collapsed)
            {
                if(!isSurveyMode)
                    return true;
            }    
            else
                return false;
        }
        return false;
    }

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

添加QuantChartWindow声明部分:

<UserControl x:Class="UI.SpectrumView.Views.QuantChartView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
          xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
         xmlns:local="clr-namespace:UI.SpectrumView.Views"
          xmlns:spccon="clr-namespace:UI.SpectrumView.Converter"
         xmlns:ui="clr-namespace:UI.Converter;assembly=Comp.UI"
         mc:Ignorable="d" 
         **x:Name="QuantChartWindow"**
         d:DesignHeight="450" d:DesignWidth="800" Background="{DynamicResource DefaultColor}">

代码隐藏文件

 public partial class QuantChartView : UserControl, IView
{
    QuantChartViewModel _viewModel;
    public QuantChartView(QuantChartViewModel vm)
    {
        InitializeComponent();
        this.DataContext = vm;
        _viewModel = vm;
        vm.Chart1 = Chart1;
        vm.Chart2 = Chart2;
        vm.GridChart2 = GridChart2;
        vm.View = this;

    }

}

查看模型类 QuantChartViewModel.cs

 public class QuantChartViewModel : DockWindowViewModel
{
    private readonly IEventAggregator _eventAggregator;
    private readonly IUnityContainer _container;
    private ICommonService _common;
   public QuantChartViewModel(IUnityContainer container, IEventAggregator eventAggregator, ICommonService common)
    {
       this._container = container;
        this.QuantViewModel = container.Resolve<QuantViewModel>();
        _common = common;
    }
     private bool _isSurveyModeEnabled =false;
     public bool IsSurveyModeOn
     {
       get
        {
            return QuantViewModel.IsEDSSurveyMode;
        }
     }
    private Visibility _commonProgressVisibility;
     public bool CommonProgressVisibility
     {
       get
        {
            return _common.CommonProgressVisibility;
        }
     }

}

完整的xml代码:

    <UserControl x:Class="UI.SpectrumView.Views.QuantChartView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup- 
             compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
              xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
             xmlns:local="clr-namespace:UI.SpectrumView.Views"
              xmlns:spccon="clr-namespace:UI.SpectrumView.Converter"
             xmlns:ui="clr-namespace:UI.Converter;assembly=Comp.UI"
             mc:Ignorable="d" 
             x:Name="QuantChartWindow"
             d:DesignHeight="450" d:DesignWidth="800" Background=" 
             {DynamicResource DefaultColor}">
  <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto">
        <TabControl Name="TabControl1" HorizontalAlignment="Stretch" 
           Background="{DynamicResource DefaultColor}" Margin="0,0,0,0" 
               SelectedIndex="{Binding TabSelectedIndex}">
            <TabItem Header="{Binding Path=tbGraph,  Source={StaticResource 
               LRWpf}}" Controls:ControlsHelper.HeaderFontSize="16" 
                 x:Name="tabControlItem" >

                <StackPanel Name="ChartPanel">

                    <StackPanel Orientation="Horizontal">
                        <ListView MinHeight="30" x:Name="lstChartMode" 
                           Width="120" >
                            <Rectangle Fill="{DynamicResource 
                                DefaultIconColor}" Height="25" Width="25"  
                                   Margin="5,0,0,0" >
                            </Rectangle>

                        </ListView>
                    </StackPanel>
                    <c1:C1Chart Name="Chart1" ChartType="{Binding 
                       SelectedChartType}" Palette="Module"  Margin="0,10,0,0">
                        <ContextMenuService.ContextMenu>
                            <ContextMenu>
                                 <MenuItem IsCheckable="False" 
                                       x:Name="MnuSendToFolder" Header=" 
                                       {Binding Path=SendToFolder, Source= 
                                       {StaticResource LRWpf}}" Command=" 
                                       {Binding SendToFolderCommand}">
                                     <MenuItem.IsEnabled>
                                        <MultiBinding Converter=" 
                                           {StaticResource 
                                                 VisibilityConverter}">
                                            <Binding 
                                              ElementName="QuantChartWindow" 
                                          Path="DataContext.IsSurveyModeOn"/>
                                            <Binding 
                                              ElementName="QuantChartWindow" 
                                Path="DataContext.CommonProgressVisibility"/>
                                        </MultiBinding>
                                       </MenuItem.IsEnabled>
                                    </MenuItem>
                                </ContextMenu>
                        </ContextMenuService.ContextMenu>
                    </c1:C1Chart>
                </StackPanel>
            </TabItem>
        </TabControl>
        </ScrollViewer>
    </Grid>
   </UserControl>

【问题讨论】:

  • 当您没有显示多绑定转换器的代码时,很难提供帮助。但一般来说,当属性的值还没有被赋值时,UnsetValue 会被移交
  • @AndersH :发布了代码的转换器部分。请看一下
  • 请发布代码的所有相关部分。 QuantChartWindow 到底设置在哪里?视图模型属性声明是什么样的?您在 Visual Studio 的输出窗口中观察到哪些数据绑定错误?我的猜测是 ElementName 解析失败。
  • 发布了代码的其他相关部分@Clemens
  • Visual Studio 的输出窗口中是否有任何数据绑定错误消息?

标签: .net wpf xaml data-binding multibinding


【解决方案1】:

另一种避免按名称绑定的方法可能如下:

<ContextMenuService.ContextMenu> <ContextMenu>
 <MenuItem IsCheckable="False" x:Name="MnuSendToFolder" Header="{Binding Path=SendToFolder, 
      Source={StaticResource LRWpf}}"   Command="{Binding SendToFolderCommand}" >
   <MenuItem.IsEnabled>
      <MultiBinding Converter="{StaticResource VisibilityConverter}">
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=xmln_to_your_lib:QuantChartView}" Path="DataContext.IsSurveyModeOn" />
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=xmln_to_your_lib:QuantChartView}" Path="DataContext.CommonProgressVisibility" />
      </MultiBinding> 
    </MenuItem.IsEnabled>
 </MenuItem>

在获得有关您的场景的少量信息后进行编辑

您不应该引用DataContext.&lt;your_property&gt;,因为 ContextMenuService DataContext 应该与QuantChartWindow 相同。

所以代码应该是:

<ContextMenuService.ContextMenu>   <ContextMenu>
 <MenuItem IsCheckable="False" x:Name="MnuSendToFolder" Header="{Binding Path=SendToFolder, 
      Source={StaticResource LRWpf}}"   Command="{Binding SendToFolderCommand}" >
   <MenuItem.IsEnabled>
      <MultiBinding Converter="{StaticResource VisibilityConverter}">
           <Binding Path="IsSurveyModeOn" />
           <Binding Path="CommonProgressVisibility" />
      </MultiBinding> 
    </MenuItem.IsEnabled>
 </MenuItem>

还请仔细检查您的 ViewModel 是否实现了INotifyPropertyChanged 接口,否则绑定将无法正常工作。

【讨论】:

  • 你能告诉我你所说的 xmln_to_your_lib 到底是什么意思吗?我的视图模型类 QuantChartViewModel 的命名空间是什么?我有点迷茫
  • @Anupriya 是的
  • 不!仍然没有运气:(我是Multibinding的新手,因此在这段代码中苦苦挣扎。@trix
  • 请分享您添加 ContextMenuService 的 XAML 代码
  • 已在问题中更新。请看一下
【解决方案2】:

您需要在转换器中进行更多验证:

  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
     if ((values != null) && 
         (values.Length == 2) &&
         (values[0] != null) &&
         (values[1] != null) &&
         (values[0] != DependencyProperty.UnsetValue) &&
         (values[1] != DependencyProperty.UnsetValue) &&
         (values[0] is bool) &&
         (values[1] is Visibility))
     {
        Visibility visvalue = (Visibility)values[1];
        bool isSurveyMode = (bool)values[0];
        if (visvalue == Visibility.Hidden || visvalue == Visibility.Collapsed)
        {
           if (!isSurveyMode)
              return true;
        }
        else
           return false;
     }
     return false;
  }

这是因为可以在您的 XAML 完全呈现之前调用转换器。我没有检查您的 XAML 或其他代码中是否有其他问题。所以也许这不足以解决你的问题,但它是它的一部分

【讨论】:

  • 实际上,我遇到的问题是上面的另一个绑定(ChartType 绑定到 SelectedChartType)。但是对于我的绑定,它不会转到 ViewModel 中绑定属性的 getter 部分。因此,我想 XAML 呈现应该不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
相关资源
最近更新 更多