2013-08-20 124 views
2

爲了進入WPF世界並習慣綁定,我創建了一個用於定義搜索過濾器的用戶控件。根據所需過濾器,用戶可以輸入文本,選擇日期或在組合框中選擇一個項目。下面是與創建的搜索控制的三個實例,不同類型的各爲一例子: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根據設置的海顯示正確的組件(文本框,日期選擇器或組合框) rchType。爲此,已創建xxxVisibility依賴項屬性和屬性(它們在SearchTypeProperty通知屬性更改事件時正在設置)。由於沒有理由將它們公開(它們僅在SearchControl內部使用),所以我將它們私有化; MSDN指出綁定的屬性必須是公共的。該項目編譯和運行沒有問題,但錯誤顯示綁定xxxVisibility屬性與消息「公衆成員預期」(不知道是否它的視覺工作室或resharper告訴我這一點)。

我的方法是根據WPF概念正確創建此用戶控件嗎? 如果xxxVisibility屬性是公開的(事件雖然我不想公開它們)?

+1

如何讓他們作爲普通的'CLR'屬性並在你的類上實現'INPC'? –

+0

這可能會訣竅。從概念上講,我仍然遇到了一個問題,因爲通過INotifyPropertyChanged.PropertyChanged引發的公共事件旨在用於用戶控件內部,但對外界沒有用處。 – Philippe

+2

綁定屬性必須是公共的。綁定將失敗,您可以在VS Output窗口中驗證失敗。 –

回答

3

這是一個很難回答的問題,而不僅僅是「評論」。我個人認爲,您的UserControl寫得很好,據我所知,不會違反任何規則。雖然我沒有看到宣稱privateDependencyProperty有任何問題,但它的不尋常。在這種情況下,開發商往往選擇實施publicRead Only DependencyPropertyprivateDependencyPropertyKey代替:

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類型的屬性,而不是BoolToVisibilityConverter S結合bool值,但再一次......這是你的特權。總的來說,做得好! :)

+0

謝謝:)對不起,'模糊'的問題,我想檢查我是否做了根本錯誤的地方。我選擇了公開Visibility屬性來避免額外的bool-> visibility轉換器:) – Philippe