绑定可见性任何父

时间:2016-07-25 14:45:22

标签: c# wpf

您好这两种不同的模式来绑定来自父级属性的可见性。 对于标准控制,可以使用这个:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<Button x:Name="buttonTest" Width="75" Visibility="{Binding IsModify, Converter={StaticResource BoolToVis}}"/>

但是对于我的usercontrol我只有这种方式来绑定可见性,否则不起作用:

  <local:UserControl4 Height="100" Width="100" Visibility="{Binding ElementName=Window1,Path=IsModify,Converter={StaticResource BoolToVis}}"/>

我的问题是为什么我需要在我的控件可见性中传递元素名称和ParentProperty,但是对于按钮号?

这是codeBehind

 public static readonly DependencyProperty IsModifyProperty =
      DependencyProperty.Register("IsModify", typeof(Boolean), typeof(MainWindow), new PropertyMetadata(false));

    [DefaultValue(false)]
    public Boolean IsModify
    {
        get { return (Boolean)GetValue(MainWindow.IsModifyProperty); }
        set
        {
            SetValue(MainWindow.IsModifyProperty, value);
            this.OnPropertyChanged("IsModify");
        }
    }

这是构造函数

 public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

这里是复制错误的源代码。 你需要一个带有一个窗口和一个用户控件的项目。

窗口的源代码 ---- XAML ----

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:XTesting" x:Name="windowTest" x:Class="XTesting.WindowTest"
    Title="WindowTest" Height="300" Width="583.908">

<Window.Resources>
    <ResourceDictionary>
        <BooleanToVisibilityConverter x:Key="BoolToVis"/>
    </ResourceDictionary>
</Window.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <local:UserControl4 
        HorizontalAlignment="Left" 
        Height="65" 
        Margin="300,30,0,0" 
        VerticalAlignment="Top" 
        Width="230" 
        Visibility="{Binding IsModify, Converter={StaticResource BoolToVis}}" 
        Background="#FFF86161" Description="Custom Control"/>

    <Button x:Name="buttonTest" 
            Content="Modify" 
            HorizontalAlignment="Left" 
            Margin="45,30,0,0" 
            VerticalAlignment="Top" 
            Width="225" 
            Visibility="{Binding IsModify, Converter={StaticResource BoolToVis}}" 
            Height="65"/>

    <Button x:Name="button" 
            Content="Skisem (Click me)" 
            HorizontalAlignment="Left" 
            Height="75" 
            Margin="225,160,0,0" 
            VerticalAlignment="Top" 
            Width="135" 
            Click="button_Click_1"
            Cursor="Hand"/>
</Grid>

这是窗口的代码隐藏

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Shapes;
namespace XTesting
{
/// <summary>
/// Interaction logic for WindowTest.xaml
/// </summary>
public partial class WindowTest : Window
{
    public static readonly DependencyProperty IsModifyProperty =
    DependencyProperty.Register("IsModify", typeof(Boolean), typeof(WindowTest), new PropertyMetadata(false));
    [DefaultValue(false)]
    public Boolean IsModify
    {
        get { return (Boolean)GetValue(WindowTest.IsModifyProperty); }
        set
        {
            SetValue(WindowTest.IsModifyProperty, value);
            this.OnPropertyChanged("IsModify");
        }
    }

    public WindowTest()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void button_Click_1(object sender, RoutedEventArgs e)
    { 
        IsModify = !IsModify;
    }

    #region - INotifyPropertyChanged implementation -
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion - INotifyPropertyChanged implementation -
}
}

这是usercontrol的源代码 XAML:

<UserControl x:Class="XTesting.UserControl4"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="37" d:DesignWidth="310" MinWidth="7"
         MouseLeftButtonUp="Selector1_MouseLeftButtonUp" FontSize="20">

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>              
        </ResourceDictionary.MergedDictionaries>  
    </ResourceDictionary>
</UserControl.Resources>


<Grid x:Name="GridRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="37*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="51"/>
        <ColumnDefinition Width="259*"/>
    </Grid.ColumnDefinitions>

    <TextBox x:Name="TextBoxDescription"
             Margin="0"
             TextWrapping="Wrap" 
             Grid.Column="1" 
             Text="{Binding Description}" 
             Background="{x:Null}" 
             BorderBrush="{x:Null}" 
             Foreground="{Binding Foreground,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 
             FontSize="{Binding FontSize,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" 
             VerticalContentAlignment="Center" 
             IsReadOnly="True" 
             SelectionBrush="{x:Null}" 
             BorderThickness="0"
             Focusable="False"
             IsTabStop="False"
             IsUndoEnabled="False"
             AllowDrop="False"
             Padding="1,0,0,0"
             MaxLines="1"
             />
</Grid>

这是背后的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 XTesting
{
/// <summary>
/// Interaction logic for UserControl4.xaml
/// </summary>
public partial class UserControl4 : UserControl, INotifyPropertyChanged
{
    #region - Delegate -
    public delegate void ClickHandler(Object sender, RoutedEventArgs e);       
    #endregion - Delegate -
    #region - Events -
    public event ClickHandler Click;      
    #endregion - Events -

    #region - Dependency Properties mandatory for Binding -
    public static readonly DependencyProperty DescriptionProperty =
        DependencyProperty.Register("Description", typeof(String), typeof(UserControl4), new PropertyMetadata(String.Empty));      
    #endregion - Dependency Properties for Binding -

    #region - Properties -       
    /// <summary>
    /// Gets or sets the description
    /// </summary>
    [Category("Common"), Description("gets or sets The description")]
    public String Description
    {
        get { return (String)GetValue(UserControl4.DescriptionProperty); }
        set
        {
            SetValue(UserControl4.DescriptionProperty, value);
            this.OnPropertyChanged("Description");
        }
    }
    #endregion - Properties -

    public UserControl4()
    {
        InitializeComponent();
        this.DataContext = this;
    }
    private void Selector1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (Click != null) Click(sender, e);           
    }

    #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 - INotifyPropertyChanged implementation -

}
}

我认为问题出在构造函数This.datacontext = this; 但如果我想要绑定属性描述,这是必须的。

提前致谢

1 个答案:

答案 0 :(得分:1)

您应该在DataContext元素而不是GridRoot类本身上添加用户控件UserControl4。用户控件的使用应主要由实例化代码控制,只有其内容应由用户控件本身控制。

另外,我更喜欢在Loaded事件而不是构造函数上分配数据上下文,但这可能仅仅是我个人的偏好。

<UserControl x:Class="XTesting.UserControl4" Loaded="UserControl4_Loaded" ...

// ...

private void UserControl4_Loaded(object sender, RoutedEventArgs e)
{
    GridRoot.DataContext = this;
}