使用BooleanToVisibility转换器隐藏网格中的列,该列是WPF中的布局元素

时间:2015-04-14 18:25:21

标签: c# wpf mvvm

我正在尝试使用Boolean到Visibility Converter绑定GRID列的visibility属性。即使bool值为false,Grid也始终可见。请帮我解决这个问题。代码对数据网格完全正常,但对于网格则不行。这是代码。

 <Window x:Class="MyApp.FirstWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewmodel="clr-namespace:MyApp.ViewModel" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;  assembly=System.Windows.Interactivity"
    xmlns:y="clr-namespace:MyApp.Framework.Converter"
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4" 
    DataContext="{Binding MyAppViewModel, Source={StaticResource Locator}}"
    MinHeight="530" MinWidth="275" Height="530" Width="275" Title="{Binding Title}"  >

 <Window.Resources>     
    <y:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
</Window.Resources>
  <Grid Margin="5">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>     
    <Grid Grid.Row="1" Grid.Column="1" Name="gridTest"
       DataContext="{Binding GridDataContext, Mode=TwoWay}"   
       Visibility="{Binding GridVisibility, Mode= TwoWay, Converter=   {StaticResource boolToVisibilityConverter}}" >
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label >Date</Label>
        <Label Grid.Column="1" Content="{Binding Date}" />

        <Label Grid.Row="1">Time</Label>
        <Label Grid.Row="1" Grid.Column="1" Content="{Binding Time}"/>
        </Grid>
</Grid>

BoolToVisibilityconverter.cs

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Windows;
  using System.Windows.Data;
  using System.Globalization;

  namespace MyApp.Framework.Converter
  {
   public sealed class BoolToVisibilityConverter : IValueConverter
    {

    public object Convert(object value, Type targetType, object     parameter,         System.Globalization.CultureInfo culture)
    {
        if (parameter == null)
        {
            return ((bool)value == true) ? Visibility.Visible : Visibility.Hidden;
        }
        else if (parameter.ToString() == "Inverse")
        {
            return ((bool)value == true) ? Visibility.Collapsed : Visibility.Visible;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

MyAppViewModel.cs

public class MyAppViewModel : ViewModelBase, INotifyPropertyChanged
{

     private bool _isGridVisible = false;

     private bool _isLabelVisible = false;
     private MyItem _gridDataContext;
     public MyItem GridDataContext
    {
        get { return _gridDataContext; }
        set
        {
            _gridDataContext = value;
            OnPropertyChanged("GridDataContext");
        }
    }

     public bool IsLabelVisible
    {
        get
        {
            return _isLabelVisible;
        }

        set
        {
            if (_isLabelVisible == value)
            {
                return;
            }

            _isLabelVisible = value;
            OnPropertyChanged("IsLabelVisible");
        }
    }
    public bool GridVisibility
    {
        get
        {
            return _isGridVisible;
        }

        set
        {
            if (_isGridVisible == value)
            {
                return;
            }

            _isGridVisible = value;
            OnPropertyChanged("GridVisibility");
        }
    }


    /// <summary>-
    /// Initializes a new instance of the AppViewModel class.
    /// </summary>      
    public AppViewModel()
    {
        _gridDataContext = new MyItem();
        //other code.
    }
  private void UpdateMyItem()
    {
        try
        {
            bool wasSet = false;

            if (test== null)
            {
                SetVisible(false, "No feature selected.");
            }
            else
            {
                SetVisible(false, String.Format("No test         
                information  selected for my item {0}.",    
                 test.name.ToString().PadLeft(5, '0')));
            }
         }
   private void SetVisible(bool wasSet, string msg)
    {

        //under construction
        if (wasSet )
        {
            Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
            {
                GridVisibility = true;
                IsLabelVisible = false;

            });
        }
        else if (!wasSet )            
        {
            Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
            {
                GridVisibility = false;
                IsLabelVisible = true;
                LabelContent = msg;

            });
        }
    }

}

}

我还没有找到适合我正在做的事情的答案。博客有隐藏/显示Datagrid列的答案,而不是Grid布局元素。这可能吗?我的XAML是Grid的Visibility属性吗?谢谢你的帮助。

解决方案:MyAppViewModel.cs

      private void SetVisible(bool wasSet, string msg)
      {  
         if (wasSet)
         {
             Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
             {
                 GridDataContext.GridVisibility = true;
                IsLabelVisible = false;                   
             });
         }
         else if (!wasSet)            
        {
             Dispatcher.CurrentDispatcher.DynamicInvoke(delegate()
             {
                 GridDataContext.GridVisibility = false;           

                 IsLabelVisible = true;
                 LabelContent = msg;                   
             });
         }
     }

1 个答案:

答案 0 :(得分:0)

正如@ Ayyappan Subramanian所述,由于DataContexts的不同而导致。

Window的上下文是MyAppViewModel已实现GridVisibility属性,但Grid的上下文是GridDataContextMyAppViewModel属性的值(typeof { {1}})。

因此,在绑定MyItem

时需要指向正确的DataContext
Visibility

或者如果这不是一个选项,请更改<Grid Grid.Row="1" Grid.Column="1" Name="gridTest" DataContext="{Binding GridDataContext}" Visibility="{Binding DataContext.GridVisibility, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Converter={StaticResource BoolToVisibilityConverter}}"> 的实现以包含给定的属性。

MyItem