Border
内有Label
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
变量与border Visibility
属性绑定?
答案 0 :(得分:26)
您不需要制作任何转换器。
为边框的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>
然后在视图模型中创建属性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;
。
答案 1 :(得分:25)
如果您已在viewmodel中拥有bool变量,则有两件事要做:
将其设为属性,例如:
public bool vis { get; set; }
然后您需要为您的财产提供可见性转换器:
这里描述:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/3c0bef93-9daf-462f-b5da-b830cdee23d9
该示例假定您有一个viewmodel并使用Binding
以下是我从您的代码段中创建的一些演示代码:
ViewModel:
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;
}
}
}
答案 2 :(得分:5)
你不能绑定字段。您只能绑定公共属性或依赖项属性。
使用公共属性(您必须实现INotifyPropertyChanged
接口才能拥有property-&gt;绑定):
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>
答案 3 :(得分: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>
答案 4 :(得分: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();
答案 5 :(得分:0)
使用 INotifyPropertyChanged 和@Ladislav Ondris 的示例。连同以下绑定 Visibility="{x:Bind Visibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 为我工作。未使用 Visibility.Collapsed 和 Visbility.Visible 以其他方式显示更新。