WPF用户控件内的绑定

时间:2013-08-20 10:23:20

标签: c# wpf binding

为了进入WPF世界并习惯绑定,我创建了一个用户控件来定义搜索过滤器。根据所需的过滤器,用户可以输入文本,选择日期或选择组合框中的项目。这是一个包含已创建搜索控件的三个实例的示例,每个实例都有不同的类型:

Search filter example

好消息是,一切正常,但我不确定是否一切都按预期完成。

SearchUserControl.xaml:

<UserControl x:Class="Zefix.View.UserControls.SearchUserControl"
             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="82" 
             d:DesignWidth="300" 
             Height="Auto"
             x:Name="SearchUserControlRoot">
    <Grid>
        <StackPanel>
            <Label Name="LabelHeaderText" Content="{Binding HeaderText, ElementName=SearchUserControlRoot}" />
            <TextBox Name="TextBoxSearchText" Text="{Binding SearchValue, ElementName=SearchUserControlRoot}" Visibility="{Binding TextBoxVisiblity, ElementName=SearchUserControlRoot}" />
            <DatePicker Name="DatePickerSearch" SelectedDate="{Binding SearchValue, ElementName=SearchUserControlRoot}" Visibility="{Binding DatePickerVisiblity, ElementName=SearchUserControlRoot}" />
            <ComboBox Name="ComboBoxSearch" Text="{Binding SearchValue, ElementName=SearchUserControlRoot}" ItemsSource="{Binding AvailableValues, ElementName=SearchUserControlRoot}" Visibility="{Binding ComboBoxVisiblity, ElementName=SearchUserControlRoot}" IsEditable="True" />
        </StackPanel>
    </Grid>
</UserControl>

SearchUserControl.xaml.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using Zefix.DataAccess;

namespace Zefix.View.UserControls {
    /// <summary>
    ///     Interaction logic for SearchUserControl.xaml
    /// </summary>
    public partial class SearchUserControl {

        #region Public Dependency Properties

        /// <summary>
        /// The search value property
        /// </summary>
        public static readonly DependencyProperty SearchValueProperty =
            DependencyProperty.Register("SearchValue", typeof (object), typeof (SearchUserControl));

        /// <summary>
        /// The available values property
        /// </summary>
        public static readonly DependencyProperty AvailableValuesProperty =
            DependencyProperty.Register("AvailableValues", typeof (IEnumerable<object>), typeof (SearchUserControl));

        /// <summary>
        /// The search type property
        /// </summary>
        public static readonly DependencyProperty SearchTypeProperty =
            DependencyProperty.Register("SearchType", typeof (SearchType), typeof (SearchUserControl));

        /// <summary>
        /// The header text property
        /// </summary>
        public static readonly DependencyProperty HeaderTextProperty =
            DependencyProperty.Register("HeaderText", typeof (string), typeof (SearchUserControl));

        #endregion

        #region Private Dependency Properties

        /// <summary>
        /// The combo box visiblity property
        /// </summary>
        private static readonly DependencyProperty ComboBoxVisiblityProperty =
            DependencyProperty.Register("ComboBoxVisiblity", typeof (Visibility), typeof (SearchUserControl));

        /// <summary>
        /// The text box visiblity property
        /// </summary>
        private static readonly DependencyProperty TextBoxVisiblityProperty =
            DependencyProperty.Register("TextBoxVisiblity", typeof (Visibility), typeof (SearchUserControl));

        /// <summary>
        /// The date picker visiblity property
        /// </summary>
        private static readonly DependencyProperty DatePickerVisiblityProperty =
            DependencyProperty.Register("DatePickerVisiblity", typeof (Visibility), typeof (SearchUserControl));

        #endregion

        #region Public Properties

        /// <summary>
        ///     Gets or sets the type of the search.
        /// </summary>
        /// <value>
        ///     The type of the search.
        /// </value>
        public SearchType SearchType {
            get { return (SearchType) GetValue(SearchTypeProperty); }
            set { SetValue(SearchTypeProperty, value); }
        }

        /// <summary>
        ///     Gets or sets the header text.
        /// </summary>
        /// <value>
        ///     The header text.
        /// </value>
        public string HeaderText {
            get { return (string) GetValue(HeaderTextProperty); }
            set { SetValue(HeaderTextProperty, value); }
        }

        /// <summary>
        /// Gets or sets the available values.
        /// </summary>
        /// <value>
        /// The available values.
        /// </value>
        public IEnumerable<object> AvailableValues {
            get { return (IEnumerable<object>) GetValue(AvailableValuesProperty); }
            set { SetValue(AvailableValuesProperty, value); }
        }

        /// <summary>
        /// Gets or sets the search value.
        /// </summary>
        /// <value>
        /// The search value.
        /// </value>
        public object SearchValue {
            get { return GetValue(SearchValueProperty); }
            set { SetValue(SearchValueProperty, value); }
        }

        #endregion

        #region Private Properties

        /// <summary>
        /// Gets or sets the combo box visiblity.
        /// </summary>
        /// <value>
        /// The combo box visiblity.
        /// </value>
        private Visibility ComboBoxVisiblity {
            get { return (Visibility) GetValue(ComboBoxVisiblityProperty); }
            set { SetValue(ComboBoxVisiblityProperty, value); }
        }

        /// <summary>
        /// Gets or sets the date picker visiblity.
        /// </summary>
        /// <value>
        /// The date picker visiblity.
        /// </value>
        private Visibility DatePickerVisiblity {
            get { return (Visibility) GetValue(DatePickerVisiblityProperty); }
            set { SetValue(DatePickerVisiblityProperty, value); }
        }

        /// <summary>
        /// Gets or sets the text box visiblity.
        /// </summary>
        /// <value>
        /// The text box visiblity.
        /// </value>
        private Visibility TextBoxVisiblity {
            get { return (Visibility) GetValue(TextBoxVisiblityProperty); }
            set { SetValue(TextBoxVisiblityProperty, value); }
        }

        #endregion

        #region Constructor

        /// <summary>
        ///     Initializes a new instance of the <see cref="SearchUserControl" /> class.
        /// </summary>
        public SearchUserControl() {
            InitializeComponent();

            DependencyPropertyDescriptor pd = DependencyPropertyDescriptor.FromProperty(SearchTypeProperty, typeof (SearchUserControl));
            pd.AddValueChanged(this, OnSearchTypePropertyChanged);

            // Initialize default parameters
            SearchType = SearchType.Unknown;
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Called when the search type property has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void OnSearchTypePropertyChanged(object sender, EventArgs e) {

            // Hide all editors
            DatePickerVisiblity = Visibility.Collapsed;
            ComboBoxVisiblity = Visibility.Collapsed;
            TextBoxVisiblity = Visibility.Collapsed;

            // Make the correct editor visible
            switch (SearchType) {
                case SearchType.Date:
                    DatePickerVisiblity = Visibility.Visible;
                    break;
                case SearchType.TextSelection:
                    ComboBoxVisiblity = Visibility.Visible;
                    break;
                case SearchType.Text:
                    TextBoxVisiblity = Visibility.Visible;
                    break;
            }
        }

        #endregion
    }
}

从父控件实例化搜索控件:

        <ribbon:Tab Label="Search">
            <ribbon:Group Padding="0,5,0,5">
                <customcontrols:SearchUserControl x:Name="SearchUserControlCompanyName" HeaderText="company name" Margin="5,0,0,0" SearchType="Text" VerticalAlignment="Center" VerticalContentAlignment="Center" />
                <customcontrols:SearchUserControl x:Name="SearchUserControlCompanyNationality" HeaderText="company nationality (ISO3 code)" Margin="5,0,0,0" SearchType="TextSelection" AvailableValues="{Binding Path=CompaniesViewModel.ISO3Codes}" VerticalAlignment="Center" />
                <customcontrols:SearchUserControl x:Name="SearchUserControlDateFounded" HeaderText="date founded" Margin="5,0,0,0" SearchType="Date" VerticalAlignment="Center" VerticalContentAlignment="Center" />
                <ribbon:Button Context="StatusBarItem" Name="ButtonApplyFilter" Label="Search" ImageSourceSmall="/Resources/search_magnifying_glass_find.png" Margin="5,0,0,0" VerticalAlignment="Center" Click="OnButtonApplyFilterClicked" Command="{Binding Path=ApplyFilterCommand}" ScreenTipHeader="Apply the search filter" VerticalContentAlignment="Center" VariantSize="Large" />
            </ribbon:Group>
        </ribbon:Tab>

在SearchControl中,我想根据设置的SearchType显示正确的组件(文本框,日期选择器或组合框)。为此,已创建xxxVisibility依赖项属性和属性(当SearchTypeProperty通知属性更改事件时,它们将被设置)。因为没有理由将它们公开为公开(它们仅在SearchControl中使用),所以我将它们设为私有; MSDN声明绑定属性必须是公共的。该项目编译并运行没有问题,但是正在显示绑定的xxxVisibility属性的错误,并显示消息“Public member expected”(无法判断它是visual studio还是resharper告诉我)。

我在WPF概念方面创建此用户控件的方法是否正确? xxxVisibility属性是否应该是公共的(尽管我不想公开它们,但是事件?)

1 个答案:

答案 0 :(得分:4)

这是一个非常难以回答的问题,而不仅仅是评论&#39;上。在我个人看来,你的UserControl写得很好,据我所知,并没有违反任何规则。虽然我在宣布private DependencyProperty时没有看到任何问题,但 是不寻常的。在这种情况下,开发人员通常选择使用public Read Only DependencyProperty来实现private DependencyPropertyKey

private static readonly DependencyPropertyKey ComboBoxVisiblityPropertyKey
    = DependencyProperty.RegisterReadOnly("ComboBoxVisiblity", typeof(int), 
    typeof(SearchUserControl), new PropertyMetadata(Visibility.Collapsed));

public static readonly DependencyProperty ComboBoxVisiblityProperty
    = ComboBoxVisiblityPropertyKey.DependencyProperty;

public int ComboBoxVisiblity
{
    get { return (int)GetValue(ComboBoxVisiblityProperty); }
    protected set { SetValue(ComboBoxVisiblityPropertyKey, value); }
}

一些开发人员可能也认为您创建Visibility类型的属性而不是将bool值与BoolToVisibilityConverter绑定在一起,这是不寻常的,但同样......那是你的特权。总的来说,干得好! :)