2010-06-24 118 views
2

我有一個組合框,我綁定到一個可觀察的集合,它會被更改(根據公司選擇),並且大量的公司將有一個單一的帳戶(項目),因此我想要知道如果ItemsSource中只有1個項目,使ComboBox設置SelectedItem的最佳方式是什麼,否則將其保留爲空以確保用戶選擇一個帳戶。WPF組合框自動選擇如果只有1個項目

我現在這樣做的方法是每次更改帳戶集合時檢查帳戶集合,如果它僅包含一個,則將綁定的選定項目屬性設置爲集合中的第一個項目。

這看起來很長,我需要分別實現它到每個視圖模型中,併爲每個組合框編寫最多5行代碼。

以下是我目前的代碼,但我想知道是否有可能通過擴展ComboBox控件來實現此目的?如果任何人有任何想法如何/從哪裏開始。

public CompanyGermanPower FromCompany 
    { 
     get { return _fromCompany; } 
     set 
     { 
      SetField(ref _fromCompany, value,() => FromCompany); 
      if(value!= null) 
      { 
       FromTradeAccountList = new ObservableCollection<TradeAccount>(TradeAccountAdapter.GetTradeAccounts(_session, value.ID)); 
       if (Trade != null && FromTradeAccountList.Count == 1) Trade.TradeAccountFrom = FromTradeAccountList[0]; 
      } 
     } 
    } private CompanyGermanPower _fromCompany; 

回答

6

創建一個你想要的Attached Behaviour應該相當簡單。要檢測組合框中的Items集合何時更改,您需要使用此blog post中提到的技巧。

更新:這是我的刺它(你需要到System.Windows.Interactivity引用添加到您的項目 - 你可以從Expression Blend的SDK得到它):

using System.Windows.Interactivity; 

public class SelectFirstItemComboBoxBehavior : Behavior<ComboBox> 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     (AssociatedObject.Items as INotifyCollectionChanged).CollectionChanged += HandleCollectionChanged; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     (AssociatedObject.Items as INotifyCollectionChanged).CollectionChanged -= HandleCollectionChanged; 
    } 

    private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (AssociatedObject.Items.Count == 1) 
     { 
      AssociatedObject.SelectedItem = AssociatedObject.Items.Cast<object>().First(); 
     } 
    } 
} 

這裏是你如何使用它:

<Window x:Class="ComboBoxSelectFirstBehavior.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:ComboBoxSelectFirstBehavior" 
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Grid.Resources> 
     <x:Array x:Key="MyObjects" Type="{x:Type local:MyType}"> 
      <local:MyType Name="WithChildren"> 
       <local:MyType.Children> 
        <local:MyTypeCollection> 
         <local:MyType Name="Child1"/> 
         <local:MyType Name="Child2"/> 
         <local:MyType Name="Child3"/> 
        </local:MyTypeCollection> 
       </local:MyType.Children> 
      </local:MyType> 
      <local:MyType Name="WithOneChild"> 
       <local:MyType.Children> 
        <local:MyTypeCollection> 
         <local:MyType Name="Child1"/> 
        </local:MyTypeCollection> 
       </local:MyType.Children> 
      </local:MyType> 
      <local:MyType Name="WithoutChildren"> 
        <local:MyType.Children> 
         <local:MyTypeCollection> 
         </local:MyTypeCollection> 
        </local:MyType.Children> 
       </local:MyType> 
     </x:Array> 
    </Grid.Resources> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 
    <ComboBox x:Name="FirstCombo" Grid.Row="0" ItemsSource="{StaticResource MyObjects}" DisplayMemberPath="Name"/> 

    <ComboBox Grid.Row="1" ItemsSource="{Binding ElementName=FirstCombo, Path=SelectedItem.Children}" DisplayMemberPath="Name"> 
     <i:Interaction.Behaviors> 
      <local:SelectFirstItemComboBoxBehavior/> 
     </i:Interaction.Behaviors> 
    </ComboBox> 
</Grid> 

+0

感謝這個,五個這個去吧:)看起來很有希望 – 2010-06-25 09:34:25

+0

工作很好,希望我可以多投票一次!很好的解釋和代碼! – 2010-08-25 10:48:40

2

只使用XAML:

<Style TargetType="{x:Type ComboBox}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=Items.Count, RelativeSource={RelativeSource Self}}" Value="1"> 
      <Setter Property="SelectedIndex" Value="0" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

當然,您可能希望爲該樣式添加一個鍵,並將其基於ComboBoxes的默認樣式,以使其非常有用,但我希望您明白。

+0

這對我來說是完美的解決方案,謝謝! – Stevoni 2015-09-11 14:20:54

+0

不錯,謝謝分享 – user500099 2018-02-19 13:58:40

相關問題