30

我有一个Borderwith Labelinside a Window

<Border x:Name="Border1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="21" Margin="229,164,0,0" VerticalAlignment="Top" Width="90" Opacity="0.5">
    <Grid>
        <Label Content="test"/>
    </Grid>
</Border>

我还有一个Variable

public bool vis = false;

如何将vis变量与边框Visibility属性绑定?

4

6 回答 6

50

你不需要做任何转换器。

为边框的 Visibility 属性添加绑定:

<Border x:Name="Border1" Visibility="{Binding Visibility}"    BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="21" Margin="229,164,0,0" VerticalAlignment="Top" Width="90" Opacity="0.5">
    <Grid>
        <Label Content="test"/>
    </Grid>
</Border>

然后在您的 ViewModel 中创建 Visibility 属性:

private Visibility visibility;
public Visibility Visibility
    {
        get
        {
            return visibility;
        }
        set
        {
            visibility = value;

            OnPropertyChanged("Visibility");
        }
    }

现在您可以将 Visible 或 Hidden 设置为 Visibility 属性,如下所示:

Visibility = Visibility.Visible;
// or
Visibility = Visibility.Hidden;

Visibility 枚举位于 System.Windows 命名空间中,因此您的 ViewModel 必须包含using System.Windows;.

于 2016-05-20T17:42:14.673 回答
40

如果你已经在视图模型中有你的 bool 变量,你有两件事要做:

  1. 使其成为一个属性,例如:

    public bool vis { get; set; }

然后,您需要为您的财产使用可见性转换器:

这里描述:

http://social.msdn.microsoft.com/Forums/en/wpf/thread/3c0bef93-9daf-462f-b5da-b830cdee23d9

该示例假设您有一个视图模型并使用Binding

这是我从您的代码段中制作的一些演示代码:

视图模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace StackOverflowWpf2
{
    public class BorderViewModel : INotifyPropertyChanged
    {
        private bool borderVisible = false;

        public bool BorderVisible 
        {
            get
            {
                return borderVisible;
            }

            set
            {
                borderVisible = value;
                NotifyPropertyChanged("BorderVisible");
            }
        }

        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

XAML:

<Window x:Class="StackOverflowWpf2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
    </Window.Resources>
    <Grid>
        <Border x:Name="Border1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="21" Margin="229,164,0,0" VerticalAlignment="Top" Width="90" Opacity="0.5"
                Visibility="{Binding Path=BorderVisible, Converter={StaticResource BoolToVisConverter} }" >
            <Grid>
                <Label Content="test"/>
            </Grid>
        </Border>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="381,35,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" 
                />
    </Grid>
</Window>

一些 Codebehind 快速测试代码:(实际上是 MainWindow.xaml.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace StackOverflowWpf2
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public BorderViewModel ViewModel { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            ViewModel = new BorderViewModel();

            this.DataContext = ViewModel;

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            var vis = (this.DataContext as BorderViewModel).BorderVisible;

            (this.DataContext as BorderViewModel).BorderVisible = !vis;

        }
    }
}
于 2013-02-04T17:58:19.403 回答
7

你不能绑定字段。您只能绑定公共属性或依赖属性。

使用公共属性(您必须实现INotifyPropertyChanged接口才能拥有属性->绑定):

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private bool vis;
    public bool Vis
    {
        get { return vis; }
        set
        {
            if (vis != value)
            {
                vis = value;
                OnPropertyChanged("Vis");  // To notify when the property is changed
            }
        }
    }

    public MainWindow()
    {
        InitializeComponent();

        Vis = true;
        // DataContext explains WPF in which object WPF has to check the binding path. Here Vis is in "this" then:
        DataContext = this;          
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Vis = !Vis;  // Test Code
    }

    #region INotifyPropertyChanged implementation
    // Basically, the UI thread subscribes to this event and update the binding if the received Property Name correspond to the Binding Path element
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}

XAML 代码是:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow2" Height="233" Width="392">

    <Window.Resources>
        <!-- You can implement your own BooleanToVisibilityConverter but there is one already implemented. So the next line creates an instance of the BooleanToVisibilityConverter that you will be able to reference with the specified key -->
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Window.Resources>

    <Grid>
        <Button Content="Click on the button to test" Click="Button_Click" Margin="0,0,0,165" />
        <Border x:Name="Border1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="21" Margin="229,164,0,0" VerticalAlignment="Top" Width="90" Opacity="0.5"
                Visibility="{Binding Vis, Converter={StaticResource BooleanToVisibilityConverter}}">
            <!-- The previous line define the binding : the path = Vis and the Converter to use -->
            <Grid>
                <Label Content="test"/>
            </Grid>
        </Border>
    </Grid>
</Window>
于 2013-02-04T18:11:12.433 回答
2

首先你需要做一个财产:

private bool _vis;

public bool Vis
{
    get{return _vis;}
    set
    {
        if(_vis != value)
        {
            _vis = value;
        }
    }
}

然后你需要一个 ValueConverter。

[ValueConversion(typeof(bool), typeof(Visibility))]
    public class VisibilityConverter : IValueConverter
    {
        public const string Invert = "Invert";

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(Visibility))
                throw new InvalidOperationException("The target must be a Visibility.");

            bool? bValue = (bool?)value;

            if (parameter != null && parameter as string == Invert)
                bValue = !bValue;

            return bValue.HasValue && bValue.Value ? Visibility.Visible : Visibility.Collapsed;
        }

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

您将需要在资源中创建转换器的实例,如下所示:

<UserControl.Resources>
    <cvt:VisibilityConverter x:Key="VisibilityConverter" />
</UserControl.Resources>

然后你可以像这样绑定你的边框:

<Border x:Name="Border1" Visibility="{Binding vis, Converter={StaticResource VisibilityConverter}}>
    <Grid>
        <Label Content="test"/>
    </Grid>
</Border>
于 2013-02-04T18:11:32.130 回答
0

另一种解决方案是使用触发器样式:

<Border x:Name="Border1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="21" Margin="229,164,0,0" VerticalAlignment="Top" Width="90" Opacity="0.5">
    <Border.Style>
        <Style TargetType="Border">
            <Setter Property="Visibility" Value="Visible"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=vis, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" Value="False">
                    <Setter Property="Visibility" Value="Hidden"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
    <Grid>
        <Label Content="test"/>
    </Grid>
</Border>

在模型类中:

public class ModelClass: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    private bool _vis;
    public bool vis
    {
        get => _vis;
        set
        {
            _vis = value;
            NotifyPropertyChanged("vis");
        }
    }
}

不要忘记将 DataContext 与您的模型绑定!

DataContext = new ModelClass();
于 2020-04-16T20:17:36.160 回答
0

使用 INotifyPropertyChanged 和 @Ladislav Ondris 的示例。连同以下绑定 Visibility="{x:Bind Visibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 为我工作。没有显示更新,否则使用 Visibility.Collapsed 和 Visbility.Visible。

于 2020-12-31T03:40:14.900 回答