网格可见性绑定不起作用

4
我正在尝试绑定网格的可见性,但无法实现。
//ViewModel Class
 private Visibility _isVisiblePane = Visibility.Hidden;
        public Visibility isVisiblePane { 
            get
            {
                return _isVisiblePane;
            }
            set
            {

                _isVisiblePane = value;
                RaisePropertyChanged(() => "isVisiblePane");
            }
        }
//xaml code
<Grid Visibility="{Binding Path=isVisiblePane}">
....My Content....
</Grid>

在调试过程中,该程序将值设置为hidden,但是当我更改_isVisiblePane的可见性时,GUI中的可见性不会更新(在_isVisiblePane值为Visible时网格仍然隐藏)。
//in some function => on button click, value of _isVisiblePane updates to Visible but grid remains hidden.
     isVisiblePane = isLastActiveDoc() == true ? Visibility.Visible : Visibility.Hidden;

错误!在RaisePropertyChanged("isVisiblePane")行上。看起来没有这个名称的属性。

出现了'System.ArgumentException'类型的异常,但未在用户代码中处理,此异常发生在GalaSoft.MvvmLight.dll中。

PS:我已经尝试过使用bool的IValueConverter方法,仍然无法弄清问题出在哪里。有任何帮助吗?


是的,我正在更新isVisiblePane。 - Saad Abdullah
1
你需要设置绑定元素或数据上下文。因此,将Visibility={Binding Path=isVisiblePane, Source=ViewModel}进行更改。另外,请确保你的类实现了INotifyPropertyChanged接口,或者如果它是UI类,则将属性移动到DependencyProperty中。 - Gary Kaizer
1
当应用程序运行时,您是否在输出窗口中看到任何红色绑定错误? - Bradley Uffner
如果ViewModel在DataContext中且绑定错误不存在,请检查您的ViewModel是否实现了INotifyPropertyChanged接口(也许您只声明了事件?) - Icepickle
我已经更新了问题...在RaisePropertyChanged上出现错误。 - Saad Abdullah
@BradleyUffner,输出窗口没有错误。 - Saad Abdullah
3个回答

6

虽然不是正面回答,但:

  • 我认为,你的ViewModel中不应该有Visibility枚举。ViewModel应该对视图技术本身无感知(例如,INotifyPropertyChanged并不属于WPF库的一部分)。因此,应该绑定到布尔值并使用转换器
  • .NET中的公共属性通常遵循帕斯卡命名法,因此,建议将isVisiblePane改为IsPaneVisible
  • 请仔细检查您的视图DataContext。
  • 在调试模式下运行项目,并查看有关绑定的控制台消息。

我已经将isVisiblePane重命名为IsPaneVisible,但没有任何反应。输出窗口中没有控制台消息。 - Saad Abdullah
1
谢谢!在我的情况下,问题出在DataContext上:<GroupBox Grid.Row="1" DataContext="{Binding SelectedObject}" Visibility="{Binding SelectedObject, Converter={StaticResource nullToHiddenConverter}}" > 这是错误的,因为它会被解释为 SelectedObject.SelectedObject。因此,以下是正确的绑定方式:Visibility="{Binding Converter={StaticResource nullToHiddenConverter}}" - j00hi
如果你感到困惑,也请检查你的转换器。也许那里有一些错误的逻辑。 - Volodymyr Kotylo

5
  • Make sure that your ViewModel class implements INotifyPropertyChanged.
  • Make sure that RaisePropertyChanged which eventually calls PropertyChanged in the proper thread context if your view is also your UI.

    public event PropertyChangedEventHandler PropertyChanged;
    
    private void RaisePropertyChanged(String info)
    {
        if (PropertyChanged != null)            
            PropertyChanged(this, new PropertyChangedEventArgs(info));            
    }
    
  • Make sure that the Grid either has your VM as it's data context or specify the proper Source for your binding.

  • Make sure that RaisePropertyChanged has anything bound to it via

    if(RaisePropertyChanged != null) RaisePropertyChanged (....)


1
通常情况下,您首先将事件封装到一个变量中,然后再触发该事件(如果它不为null):var local = PropertyChanged; if (local != null) local.Invoke(this, new PropertyChangedEventArgs(propertyName); - Icepickle
你知道吗,你太棒了!:D 是的,我的视图模型没有实现INotifyPropertyChanged接口。我以为这是Prism而不是MVVM-Light的头疼问题。 - Saad Abdullah
@SaadAbdullah,“INotifyPropertyChanged”是WPF本身的“头疼”。 :) - Bruno Brant
耶!是时候提高我的 WPF 概念了 :P - Saad Abdullah
我忘记设置数据上下文了!!! - ConductedClever

0
Very late but everyone keeps suggestions to use a converter.  Good suggestion but still requires the use of more code behind.  You can use a data trigger as part of the style for your UI element and change visibility based on value of the bool in your model.

<Grid>
    <Grid.Style>
        <Style TargetType="{x:Type Grid}">
            <Setter Property="Visibility" Value="Collapsed" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=MyBoolValue}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接