2016-01-20 67 views
1

我在我的项目中有以下情况,我想知道什么是实现我的目标的最佳方式。组合框与“刷新”条目

目标:有一个带有itemsource绑定的组合框和一个功能类似刷新按钮(从数据库获取项目并更新组合框项目)的组合框。

目前我使用itemsource绑定(请参见下文)设置我的组合框,但目前我正忙于刷新命令的绑定。

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

如果项目是一个依赖属性与项目的列举,与刷新命令(一个ICommand)另一个依赖属性也是可用的。定义为

我的组合框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> 

的问题是,命令无法找到绑定的源,所以这个问题是我是正确的方式做,有一个解决方案,还是我在错误的方式(这会更好?)。

当然,我可以在我的组合框旁边添加一个按钮,但我想在我的组合框中添加按钮。 :)

btw .:我试图按照MVVM模式。

+0

请记住,以上示例中没有命令绑定,因为它没有工作。 :) – Thoor

+0

我很好奇的可用性。这是否意味着刷新项目总是在索引0?如果不是,如果您有大量项目,您的用户需要在组合列表中找到它。 – tgpdyk

+0

@tgpdyk关于在我的情况下的可用性是没有问题的,因为只有当特定物品不在列表中时,每年约5次的情况下刷新才是必要的。 – Thoor

回答

0

我已经通过使用后面的代码解决了这个问题。加载组合框时,创建Projects的新List<objects>,并将Refresh string(可能为"<Refresh...>")添加到列表中,最后将ItemsSource设置为该列表。使用模板选择器来显示相应的DataTemplate。当选择更改时,检查是否选择了Refresh string,如果是,请刷新并重新加载组合框。刷新时,可以尝试将选择设置回先前选择的项目或索引0,以便用户永远不能在组合框中选择“刷新”。

一些片段来演示。

在构造函数

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

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

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

你的想法

...这应该足以让你去,如果这个解决方案能够满足您的需求。

+0

@Thoor,只是好奇,如果你找到了解决你的问题?上面的帮助,还是你使用另一种方法? –

+0

我将它标记为答案,因为它与我的解决方案非常相似。我结束了将ItemsSource绑定到我的ProjectViewModels列表。当我的列表被调用时,我返回项目列表和一个从ProjectViewModel继承的RefreshViewModel。如果现在SelectedValue绑定更新,我检查给定的类型并设置项目或刷新列表。 RefreshViewModels Equals方法被重写并返回false,因此无法选择。 – Thoor