1

我正在 WPF 中构建一个视图,它应该有一个非常复杂的 ComboBox,使用 MVVM 模式和 Caliburn.Micro 框架。我对 WPF 和 Caliburn 很陌生,我希望我能在这里找到正确的答案。

这是我想象的:
扩展组合框

如您所见,它由不同种类的项目和不同的子级别组成。只有项目是可选的,而不是它们的组。除此之外,我想在组合框上显示两个附加按钮,这取决于所选项目所属的项目组:
缩小的组合框

我知道我可以:

  • 硬编码 XAML 中的组合框看起来像这样,但它对我不起作用,因为我需要在我的视图模型中拥有数据。
  • 以编程方式在我的视图模型中定义控件树并将我的组合框的内容属性绑定到它。但是在我的视图模型中创建视觉效果似乎有点错误。
  • 为组合框项创建一个视图模型(和一个视图)并设置各种属性来控制它们中的每一个的外观。
  • 创建一个全新的控件,从 ComboBox 派生并以某种方式实现它。

至于这两个按钮,我可能会将它们放在组合框的顶部,并从主视图模型控制它们的可见性。

考虑了所有这些选项后,我仍然不确定我知道自己在这里做什么。

4

1 回答 1

3

您可以使用模板重新设置 ComboBox 的样式以获得您想要的外观。
这是一个简单的例子:

XAML

<ComboBox Width="200" Height="30" ItemsSource="{Binding ItemList}">
    <ComboBox.ItemContainerStyle>
        <Style>
            <Setter Property="UIElement.IsEnabled" Value="{Binding IsSelectable}" />
        </Style>
    </ComboBox.ItemContainerStyle>
    <ComboBox.ItemTemplate>
        <DataTemplate >
            <StackPanel Orientation="Horizontal">
                <Image Name="ImageControl" Source="{Binding ImagePath}" Width="10" Height="10" />
                <Label Content="{Binding Name}" >
                    <Label.Style>
                        <Style TargetType="Label">
                            <Style.Triggers>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="Foreground" Value="Black" />
                                    <Setter Property="FontWeight" Value="Bold" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Label.Style>
                </Label>
            </StackPanel>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding IsSelectable}" Value="False">
                    <Setter TargetName="ImageControl" Property="Visibility" Value="Collapsed" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

C#

// A class to hold my data for the combobox
public class Item
{
    public string Name { get; set; }
    public bool IsSelectable { get; set; }
    public string ImagePath { get; set; }
}

// In your datacontext
public ObservableCollection<Item> ItemList { get; set; }

public ComboBoxFun()
{
    ItemList = new ObservableCollection<Item>()
    {
        new Item() { ImagePath=@"/images/up.png", Name="Item Group 1", IsSelectable=false},
        new Item() { ImagePath=@"/images/up.png", Name="Item 1", IsSelectable=true},
        new Item() { ImagePath=@"/images/up.png", Name="Item 2", IsSelectable=true},
        new Item() { ImagePath=@"/images/up.png", Name="Item 3", IsSelectable=true},
        new Item() { ImagePath=@"/images/up.png", Name="Item Group 2", IsSelectable=false},
        new Item() { ImagePath=@"/images/up.png", Name="Item 1", IsSelectable=true},
        new Item() { ImagePath=@"/images/up.png", Name="Item 2", IsSelectable=true},
        new Item() { ImagePath=@"/images/up.png", Name="Item 3", IsSelectable=true}
    };

唯一棘手的部分是,当您禁用某个项目时,它将被设置为禁用,因此您必须设置不可选择项目的样式,使其看起来正常。

这是我的结果:

结果

您可以选择任何非组项目,它的工作方式与普通 ComboBox 一样。至于您的按钮,您可以根据所选项目的数据简单地控制它们的可见性。

希望这可以帮助。

于 2013-01-31T15:57:11.153 回答