简体   繁体   English

带有“刷新”条目的组合框

[英]ComboBox with “Refresh” Entry

I've the following situation in my project and i'm wondering what's the best way to achieve my goal. 我在项目中遇到以下情况,我想知道实现目标的最佳方法是什么。

Goal: Having a combobox with itemsource binding and one entry which is functioning like a refresh button (fetching items from database and update combobox items). 目标:拥有一个带有itemsource绑定的组合框和一个功能类似于刷新按钮的条目(从数据库中获取项目并更新组合框项目)。

Currently I set up my combobox with itemsource binding (see below), but currently i'm struggling with the binding of the command for refreshing. 目前,我使用itemsource绑定设置了组合框(请参见下文),但是目前我正在为刷新命令而苦苦挣扎。

ItemsSource Binding: ItemsSource绑定:

<UserControl.Resources>
<CollectionViewSource x:Key="ProjectSource" Source="{Binding Projects, ElementName=Ancestor}"/>
    <CompositeCollection x:Key="ProjectCollection">
        <CollectionContainer Collection="{Binding Source={StaticResource ProjectSource}}"/>
        <Button Content="Refresh!"/>
    </CompositeCollection>

</UserControl.Resources>

Where Projects is a dependency property with an enumeration of items, another dependency property with the refresh command (an ICommand) is also available. 如果Projects是具有项目枚举的依赖项属性,则还可以使用带有refresh命令(ICommand)的另一个依赖项属性。

My ComboBox ist defined as follows: 我的ComboBox ist定义如下:

<ComboBox SelectedValue="{Binding Project}"
                  ItemsSource="{StaticResource ProjectCollection}"
                  VerticalContentAlignment="Center"
                  HorizontalAlignment="Left"
                  Name="Box"
                  IsHitTestVisible="{Binding IsEditable}"
                  IsEnabled="{Binding IsEnabled, Mode=OneWay, IsAsync=True}">

            <ComboBox.Resources>
                <DataTemplate DataType="{x:Type viewModels:ProjectViewModel}">
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>>
            </ComboBox.Resources>

        </ComboBox>

The problem is that the Command can't find the source of the binding, so the question is am i on the right way doing it and there is a solution, or am I on the wrong way (which would be better?). 问题是Command找不到绑定的来源,所以问题是我是在做正确的方法并且找到解决方案,还是我在做错了方法(这会更好吗?)。

Sure i could just add a button next to my combobox, but i'd like to have it in my combobox. 当然,我可以在组合框旁边添加一个按钮,但我想在组合框中添加按钮。 :) :)

Btw.: I'm trying to follow the MVVM pattern. 顺便说一句:我正在尝试遵循MVVM模式。

I have solved this issue in the past by using code behind. 我过去通过使用后面的代码解决了这个问题。 When the combobox loads, create a new List<objects> of the Projects and add a Refresh string (maybe "<Refresh...>" ) to the list, and finally setting the ItemsSource to this list. 加载组合框后,创建一个新的Projects List<objects>并将Refresh string (也许是"<Refresh...>" )添加到列表中,最后将ItemsSource设置到该列表中。 Use a template selector to show the appropriate DataTemplate. 使用模板选择器显示适当的DataTemplate。 When the selection changes, check if the Refresh string was selected, and if so, do your refresh, and reload the combobox. 选择更改后,请检查是否选择了“ Refresh string ,如果是,请刷新并重新加载组合框。 When you refresh, you can try to set the selection back to the previously selected item, or index 0, so the user can never have "refresh" selected in the combobox. 刷新时,可以尝试将选择设置回先前选择的项目或索引0,这样用户永远不会在组合框中选择“刷新”。

Some snippets to demonstrate. 一些片段来演示。

in ctor 在ctor

SelectedProjectComboBoxTemplateSelector.StringTemplate = FindResource("StringTemplate") as DataTemplate;
SelectedProjectComboBoxTemplateSelector.ProjectTemplate = FindResource("ProjectTemplate") as DataTemplate;
SelectedProjectComboBox.SelectionChanged += SelectedProjectComboBox_SelectionChanged;
SelectedProjectComboBox.ItemTemplateSelector = new SelectedProjectComboBoxTemplateSelector();

and

void SelectedProjectComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
    if (SelectedProjectComboBox.SelectedItem is string && ((string)SelectedProjectComboBox.SelectedItem) == RefreshProjectSelectionItem) {
        object current = e.RemovedItems.Count > 0 ? e.RemovedItems[0] : null;

        bool ret = RefreshData(); // from db
        if (ret) {
            LoadData(); // repopulate combobox
        } else {
            SelectedProjectComboBox.SelectedItem = current;
        }               
    }
}

and

public class SelectedProjectComboBoxTemplateSelector : DataTemplateSelector {
    public static DataTemplate StringTemplate { get; set; }
    public static DataTemplate ProjectTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
        if (item == null || Designer.IsInDesignMode) return null;

        if (item is string) return StringTemplate;
        if (item is Project) return ProjectTemplate;

        return null;
    }
}

You get the idea... This should be enough to get you going if this solution meets your needs. 您有主意...如果此解决方案满足您的需求,这应该足以使您继续前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM