简体   繁体   English

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

[英]Hide a column in the grid which is a layout element in WPF using BooleanToVisibility converter

I am trying to bind the visibility property of a GRID column using a Boolean to Visibility Converter. 我正在尝试使用布尔值将GRID列的可见性属性绑定到Visibility Converter。 The Grid is always visible even though the bool value is false. 即使bool值为false,网格也始终可见。 Please help me fix this issue. 请帮助我解决此问题。 The code works perfectly fine for a datagrid but not for a Grid .Here is the code. 该代码对于Datagrid而言运行良好,但对于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 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 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;

            });
        }
    }

}

} }

I haven't found any answers appropriate for what I am doing. 我没有找到适合我所做工作的答案。 The blogs have answers to hiding/showing Datagrid columns and not Grid layout element. 博客的答案是隐藏/显示Datagrid列,而不是Grid布局元素。 Is this possible? 这可能吗? Is my XAML for the Visibility property of the Grid OK? Grid的Visibility属性的XAML是否可以? Thanks for your help. 谢谢你的帮助。

Solution: MyAppViewModel.cs 解决方案: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;                   
             });
         }
     }

As stated by @ Ayyappan Subramanian it's due to different DataContexts. 正如@ Ayyappan Subramanian所说,这是由于不同的DataContext。

Window's context is the MyAppViewModel which has GridVisibility property implemented but Grid's context is value of GridDataContext property within MyAppViewModel (typeof MyItem ). Window的上下文是MyAppViewModel ,已实现GridVisibility属性,但Grid的上下文是MyAppViewModel (typeof MyItem )内GridDataContext属性的值。

So you need to point to the right DataContext when binding Visibility 因此,绑定Visibility时,您需要指向正确的DataContext

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

Or if this is not an option, change the implementation of MyItem to include given property. 或者,如果这不是一个选项,则更改MyItem的实现以包括给定的属性。

public class MyItem : ViewModelBase
{
    // Current implementation goes here...

    // GridVisibility implementation
    private bool _isGridVisible = false;
    public bool GridVisibility
    {
        get { return _isGridVisible; }
        set
        {
            _isGridVisible = value;
            RaisePropertyChanged();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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