网格上的可见性绑定不起作用

问题描述 投票:0回答: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>

在调试时,程序将值设置为隐藏,但是当我更改 _isVisiblePane 的可见性时,它不会更新 GUI 中的可见性(网格保持隐藏状态,而 _isVisiblePane 值是可见的)。

//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") 行上。好像没有这个名字的房产 “GalaSoft.MvvmLight.dll 中发生了‘System.ArgumentException’类型的异常,但未在用户代码中处理”

PS:我也尝试过使用 bool 的 IValueConverter 方法。但仍然不知道问题出在哪里。有什么帮助吗?

c# wpf mvvm-light
4个回答
6
投票

没有真正回答,但是:

  • 恕我直言,您的 ViewModel 中不应该有 Visibility 枚举。请注意,ViewModel 应该与视图技术本身无关(例如,要意识到 INotifyPropertyChanged 不是 WPF 库的一部分)。因此,改为绑定到布尔值并使用 converter
  • .NET 中的公共属性通常遵循 Pascal 大小写,因此,我建议将
    isVisiblePane
    更改为
    IsPaneVisible
  • 仔细检查视图的 DataContext。
  • 在调试模式下运行项目并观察控制台中有关绑定的消息。

5
投票
  • 确保您的 ViewModel 类实现 INotifyPropertyChanged。
  • 如果您的视图也是您的 UI,请确保 RaisePropertyChanged 最终在正确的线程上下文中调用 PropertyChanged。

    public event PropertyChangedEventHandler PropertyChanged;
    
    private void RaisePropertyChanged(String info)
    {
        if (PropertyChanged != null)            
            PropertyChanged(this, new PropertyChangedEventArgs(info));            
    }
    
  • 确保网格将您的虚拟机作为数据上下文,或者为您的绑定指定正确的源。

  • 确保 RaisePropertyChanged 通过

    绑定了任何内容

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


1
投票
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>

0
投票
//--------------------- ViewModel codes
public ViewModel()
{
    UpdateVisibility();
}

private Visibility _kirilmisVisibility = Visibility.Visible;
public Visibility KirilmisVisibility
{
    get { return _kirilmisVisibility; }
    set
    {
        if (_kirilmisVisibility != value)
        {
            _kirilmisVisibility = value;
            OnPropertyChanged(nameof(KirilmisVisibility));
        }
    }
}

private void UpdateVisibility()
{
    KirilmisVisibility = Visibility.Visible;
}



//--------------------- DataGridColumnVisibilityBehavior codes
public class DataGridColumnVisibilityBehavior : Behavior<DataGrid>
{
    public static readonly DependencyProperty ColumnVisibilityProperty =
        DependencyProperty.Register(nameof(ColumnVisibility), typeof(Visibility), typeof(DataGridColumnVisibilityBehavior),
            new PropertyMetadata(Visibility.Visible, OnColumnVisibilityChanged));

    public Visibility ColumnVisibility
    {
        get { return (Visibility)GetValue(ColumnVisibilityProperty); }
        set { SetValue(ColumnVisibilityProperty, value); }
    }

    public string ColumnName { get; set; }

    private static void OnColumnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is DataGridColumnVisibilityBehavior behavior && behavior.AssociatedObject != null)
        {
            behavior.UpdateColumnVisibility();
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        UpdateColumnVisibility();
    }

    private void UpdateColumnVisibility()
    {
        if (AssociatedObject == null || string.IsNullOrEmpty(ColumnName)) return;

        var column = AssociatedObject.Columns.FirstOrDefault(c => c.Header?.ToString() == ColumnName);
        if (column != null)
        {
            column.Visibility = ColumnVisibility;
        }
    }
}



<!-- View XAML codes -->
<!-- Info: Convert Class: DataGridColumnVisibilityBehavior -->
<i:Interaction.Behaviors>
    <convert:DataGridColumnVisibilityBehavior ColumnName="Kirilmis" ColumnVisibility="{Binding KirilmisVisibility}"

/>

<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Kirilmis" Width="1*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding KodID}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>
© www.soinside.com 2019 - 2024. All rights reserved.