WPF组合框自动选择只有1项 [英] WPF ComboBox Auto Select If Only 1 Item

查看:170
本文介绍了WPF组合框自动选择只有1项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我绑定到一个观察的集合,这将会改变组合框(根据公司的选择)和大量的公司将拥有一个帐户(项目),因此我想知道什么最好的办法使组合框设置的SelectedItem如果只有1中的ItemsSource项,否则将其保留为空,以确保用户选择一个帐户。



我这样做的方式此刻是每次改变时检查帐户,集合,如果它仅包含一个,设置绑定所选项目属性集合中的第一项。



这似乎长篇大论,我需要分别落实到每个视图模型,并写了5行的每个组合框代码。



以下是代码目前,我,但我如果有可能通过扩展ComboBox控件来实现这一疑惑?如果任何人有怎样/从哪里开始的任何想法。

 公共CompanyGermanPower FromCompany 
{
获得{返回_fromCompany; }

{
SetField(REF _fromCompany,价值,()=> FromCompany);
如果(值!= NULL)
{
FromTradeAccountList =新的ObservableCollection< TradeAccount>(TradeAccountAdapter.GetTradeAccounts(_session,value.ID));
如果(商品=空&放大器;!&放大器; FromTradeAccountList.Count == 1)Trade.TradeAccountFrom = FromTradeAccountList [0];
}
}
}私人CompanyGermanPower _fromCompany;


解决方案

这应该是相当简单创建的附行为,你想要做什么。为了检测当项目集合在ComboBox改变,你需要使用本的博客文章



更新:这是我在它刺(你需要添加一个 - 参考System.Windows.Interactivity到你的项目,你可以从Expression Blend中SDK)得到它:

 使用System.Windows .Interactivity; 

公共类SelectFirstItemComboBoxBehavior:行为<&组合框GT;
{
保护覆盖无效OnAttached()
{
base.OnAttached();

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

保护覆盖无效OnDetaching()
{
base.OnDetaching();
(AssociatedObject.Items为INotifyCollectionChanged).CollectionChanged - = HandleCollectionChanged;
}

私人无效HandleCollectionChanged(对象发件人,NotifyCollectionChangedEventArgs E)
{
如果(AssociatedObject.Items.Count == 1)
{
AssociatedObject.SelectedItem = AssociatedObject.Items.Cast<对象>()(第)。
}
}
}

下面是你如何使用它:

 <窗口x:类=ComboBoxSelectFirstBehavior.MainWindow
的xmlns =http://schemas.microsoft .COM / WinFX的/ 2006 / XAML /演示
的xmlns:X =http://schemas.microsoft.com/winfx/2006/xaml
的xmlns:地方=CLR的命名空间:ComboBoxSelectFirstBehavior
的xmlns:I =http://schemas.microsoft.com/expression/2010/interactivity
标题=主窗口HEIGHT =350WIDTH =525>
<网格和GT;
< Grid.Resources>
< X:数组x:键=MyObjectsTYPE ={X:类型本地:MyType的}>
<局部:MyType的名称=为children>
<局部:MyType.Children>
<局部:MyTypeCollection>
<局部:MyType的名称=Child1/>
<局部:MyType的名称=CHILD2/>
<局部:MyType的名称=Child3/>
< /地方:MyTypeCollection>
< /地方:MyType.Children>
< /地方:MyType的>
<局部:MyType的名称=WithOneChild>
<局部:MyType.Children>
<局部:MyTypeCollection>
<局部:MyType的名称=Child1/>
< /地方:MyTypeCollection>
< /地方:MyType.Children>
< /地方:MyType的>
<局部:MyType的名称=WithoutChildren>
<局部:MyType.Children>
<局部:MyTypeCollection>
< /地方:MyTypeCollection>
< /地方:MyType.Children>
< /地方:MyType的>
< / X:数组>
< /Grid.Resources>
< Grid.RowDefinitions>
< RowDefinition />
< RowDefinition />
< /Grid.RowDefinitions>
<组合框X:NAME =FirstComboGrid.Row =0的ItemsSource ={StaticResource的MyObjects}的DisplayMemberPath =名称/>

<组合框Grid.Row =1的ItemsSource ={绑定的ElementName = FirstCombo,路径= SelectedItem.Children}的DisplayMemberPath =名称>
< I:Interaction.Behaviors>
<局部:SelectFirstItemComboBoxBehavior />
< /我:Interaction.Behaviors>
< /组合框>
< /网格和GT;




I have a combo box that I bind to an observable collection, which gets changed (according to company selected) and a large number of companies will have a single account (the items) therefore I want to know what the best way to make the ComboBox set the SelectedItem if there is only 1 item in the ItemsSource, otherwise leave it as null to ensure the user chooses an account.

The way I am doing this at the moment is by checking the account collection each time it is changed, and if it contains only one, setting the bound selected item property to the first item in the collection.

This seems long winded and I would need to implement it into each view model separately and write up to 5 lines of code for each combo box.

The following is the code I currently, but I was wondering if there would it be possible to achieve this by extending the ComboBox control? And if anyone has any ideas on how/where to start.

    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;

解决方案

It should be fairly straightforward to create an Attached Behaviour that does what you want. To detect when the Items collection in the ComboBox changed, you'd need to use the trick mentioned in this blog post.

Update: Here's my stab at it (you'll need to add a reference to System.Windows.Interactivity to your project - you can get it from the 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();
        }
    }
}

Here's how you use it:

<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>

这篇关于WPF组合框自动选择只有1项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆