web-dev-qa-db-ja.com

可視性プロパティを変数にバインドする

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プロパティにバインドするにはどうすればよいですか?

20
7zawel

ビューモデルにbool変数が既にある場合は、次の2つのことを行う必要があります。

  1. 次のようなプロパティにします。

    public bool vis { get; set; }

そして、あなたはあなたの財産のための可視性コンバータが必要です:

ここで説明します:

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

この例では、ビューモデルがあり、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;

        }
    }
}
27
Mare Infinitus

コンバーターを作成する必要はありません。

境界線の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");
        }
    }

したがって、次のようにVisibilityプロパティにVisibleまたはHiddenを設定できます。

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

ただし、Visibility enumはSystem.Windows名前空間にあるため、ビューモデルにはusing System.Windows;

27
Ladislav Ondris

フィールドをバインドすることはできません。パブリックプロパティまたは依存関係プロパティのみをバインドできます。

パブリックプロパティの使用(property-> bindingを使用するには、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>
6
Cédric Bignon

最初に、visをプロパティにする必要があります。

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>
2
TrueEddie