我正在尝试使用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;
});
}
}
答案 0 :(得分:0)
正如@ Ayyappan Subramanian所述,由于DataContexts的不同而导致。
Window的上下文是MyAppViewModel
已实现GridVisibility
属性,但Grid的上下文是GridDataContext
中MyAppViewModel
属性的值(typeof { {1}})。
因此,在绑定MyItem
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