我的项目中有以下情况,我想知道实现目标的最佳方法是什么。
目标:拥有一个带有 itemsource 绑定(bind)的组合框和一个功能类似于刷新按钮的条目(从数据库中获取项目并更新组合框项目)。
目前,我使用 itemsource 绑定(bind)设置了我的组合框(见下文),但目前我正在为刷新命令的绑定(bind)而苦苦挣扎。
ItemsSource 绑定(bind):
<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>
在 Projects 是具有项目枚举的依赖属性的情况下,另一个具有刷新命令(ICommand)的依赖属性也是可用的。
我的 ComboBox 定义如下:
<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>
问题是命令找不到绑定(bind)的来源,所以问题是我是在正确的方式上做它并且有解决方案,还是我在错误的方式上(哪个会更好?)。
当然我可以在我的组合框旁边添加一个按钮,但我想把它放在我的组合框中。 :)
顺便说一句:我正在尝试遵循 MVVM 模式。
最佳答案
我过去通过使用后面的代码解决了这个问题。当组合框加载时,创建一个新的 List<objects>
的Projects
并添加 Refresh string
(也许 "<Refresh...>"
)到列表中,最后将 ItemsSource 设置为此列表。使用模板选择器显示适当的 DataTemplate。 When the selection changes, check if the Refresh string
被选中,如果是这样,请刷新并重新加载组合框。刷新时,您可以尝试将选择设置回先前选择的项目,或索引 0,因此用户永远无法在组合框中选择“刷新”。
一些片段来演示。
在 ctor
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;
}
}
您明白了...如果此解决方案满足您的需求,这应该足以让您继续前进。
关于c# - 具有 "Refresh"条目的组合框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34891069/