2011-10-26 59 views
0

在選擇ComboBox中的任何項目之前,其SelectedItem爲空,並且ComboBox本身在視覺上爲空白。一旦選擇了某項內容,用戶似乎沒有任何方法選擇「缺少選擇」(儘管可以通過在代碼中將SelectedItem設置爲null來完成)。更新UserControl中的ItemsControl(組合框)中的SelectedItem

我的組合框綁定到我的對象的ObservableCollections。我不想在每個ObservableCollection的前面添加一個「特殊的」第一個類似於null的對象。所以我藉此機會學習了一些關於編寫UserControl的內容。

問題是SelectedItem無法正常工作。也就是說,ComboBox很好地支持ObservableCollection,但從ComboBox中挑選某些內容不會更新它應該綁定到的SelectedItem

我覺得我需要將某些信息從UserControl中的ComboBox傳遞到...某處。我在正確的軌道上嗎?我應該用Google搜索什麼?

C#:

public partial class ClearableComboBox : UserControl 
{ 
    public ClearableComboBox() 
    { 
     InitializeComponent(); 
    } 

    public IEnumerable ItemsSource 
    { 
     get { return (IEnumerable)base.GetValue(ItemsSourceProperty); } 
     set { base.SetValue(ItemsSourceProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsSourceProperty = 
     DependencyProperty.Register("ItemsSource", 
      typeof(IEnumerable), 
      typeof(ClearableComboBox)); 

    public object SelectedItem 
    { 
     get { return (object)base.GetValue(SelectedItemProperty); } 
     set { base.SetValue(SelectedItemProperty, value); } 
    } 

    public static readonly DependencyProperty SelectedItemProperty = 
     DependencyProperty.Register("SelectedItem", 
      typeof(object), 
      typeof(ClearableComboBox)); 

    public string DisplayMemberPath 
    { 
     get { return (string)base.GetValue(DisplayMemberPathProperty); } 
     set { base.SetValue(DisplayMemberPathProperty, value); } 
    } 

    public static readonly DependencyProperty DisplayMemberPathProperty = 
     DependencyProperty.Register("DisplayMemberPath", 
      typeof(string), 
      typeof(ClearableComboBox)); 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     comboBox.SelectedItem = null; 
    } 
} 

XAML:

<UserControl x:Class="MyProj.ClearableComboBox" 
      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" 
      x:Name="root"> 
    <DockPanel> 
     <Button DockPanel.Dock="Left" Click="Button_Click" ToolTip="Clear"> 
      <Image Source="pack://application:,,,/img/icons/silk/cross.png" Stretch="None" /> 
     </Button> 
     <ComboBox 
      Name="comboBox" 
      ItemsSource="{Binding ElementName=root, Path=ItemsSource}" 
      SelectedItem="{Binding ElementName=root, Path=SelectedItem}" 
      DisplayMemberPath="{Binding ElementName=root, Path=DisplayMemberPath}" /> 
    </DockPanel> 
</UserControl> 

用法:

<wpfControl:ClearableComboBox ItemsSource="{Binding Path=Things}" 
           DisplayMemberPath="SomeProperty" 
           SelectedItem="{Binding Path=SelectedThing}" /> 

// Picking a Thing doesn't update SelectedThing :(

回答

1

由於組合框從Selector類這反過來從ItemsControl派生派生。所以,通過派生自UserControl,您將使用Selector類的屬性取消組合框,這可能會在內部爲您處理Selection選項。所以

public partial class ClearableComboBox : ComboBox 

,這方面你將不必重寫ItemsSource,等的DisplayMemberPath在你的類,因爲它 - 如此,我會建議,而不是從用戶控件派生它,你應該從組合框派生它像這樣已經存在於ComboBox類中。你可以隨時擴展你的課程,以提供額外的功能,在你的情況下將SelectedItem設置爲空按鈕點擊。希望這是你想要的..

EDIT(自定義控件)

這裏創建自定義的控制是你的答案,就可以開始,如果你沒有意識到這一點,看看這個起動 - http://www.wpftutorial.net/HowToCreateACustomControl.html

當你創建一個自定義控件說CustomControl1,這一個替換爲CustomControl1模板在Generic.xaml文件 -

<ControlTemplate TargetType="{x:Type local:CustomControl1}"> 
    <Border Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" 
      BorderThickness="{TemplateBinding BorderThickness}"> 
       <DockPanel> 
       <Button Name="btn" DockPanel.Dock="Left" ToolTip="Clear" Width="20"> 
        <Image Source="pack://application:,,,/img/icons/silk/cross.png" Stretch="None" /> 
       </Button> 
       <ComboBox Name="comboBox" 
          ItemsSource="{TemplateBinding ItemsSource}" 
          SelectedItem="{TemplateBinding SelectedItem}" 
          DisplayMemberPath="{TemplateBinding DisplayMemberPath}" /> 
       </DockPanel> 
    </Border> 
</ControlTemplate> 

默認情況下你的CustomControl1班級將從Control派生。取代它從ComboBox類派生,這樣你就不必申報DP的又一遍這樣的複製粘貼此代碼中有 -

public class CustomControl1 : ComboBox 
{ 
     private Button clearButton; 
     private ComboBox comboBox; 

     static CustomControl1() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 

      clearButton = GetTemplateChild("btn") as Button; 
      comboBox = GetTemplateChild("comboBox") as ComboBox; 
      clearButton.Click += new RoutedEventHandler(clearButton_Click); 
     } 

     private void clearButton_Click(object sender, RoutedEventArgs e) 
     { 
      comboBox.SelectedItem = null; 
     } 
} 

現在,您CustomControl1類是準備用在喜歡你的其他XAML文件這 -

<local:CustomControl1 ItemsSource="{Binding YourSource}" 
         SelectedItem="{Binding YourSelectedItem}" 
         Height="50" Width="200"/> 
+0

你會如何建議我通過鼠標點擊清除我的ClearableComboBox? – epalm

+0

我用自定義控件更新了我的答案。如有任何問題,請查看並告訴我。 –

+0

當我使用''它充滿了Foos,但是當我從中選擇Foo時,SelectedFoo不會更新下拉。 – epalm

0

我選擇來處理組合框的按鍵事件並辦理退出鍵按清除組合框的SelectedItem

+0

組合框是在與ShowDialog的()所示的窗口,所以ESC鍵將關閉窗口,而不是清除組合框。 – epalm

+0

我也使用delete keypress來清除組合框。 – UnhandledExcepSean

0

我認爲還有更好的方法,開發一個包裝/裝飾者ComboBox,它在ComboBox旁邊添加一個按鈕並在點擊時清除選擇。

+1

是的,這沒有幫助。我相信IsSynchronizedWithCurrentItem與底層CollectionView(或CollectionViewSource?)有關。 – epalm