Выражение мультисвязки, всегда показывающее DependencyProperty.UnsetValue в его мультиконвертере - PullRequest
0 голосов
/ 17 июня 2020
<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 являются опубликованными c свойствами модели просмотра. В функции 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;
        }
     }

}

Полный код xaml:

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

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Вам нужно больше проверки в вашем конвертере:

  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 или другим кодом. Так что, может быть, этого недостаточно для решения вашей проблемы, но это ее часть

0 голосов
/ 17 июня 2020

Другой подход, позволяющий избежать привязки по имени, может быть следующим:

<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.<your_property>, потому что 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, иначе привязка не будет работать должным образом.

...