MVVM WPF Combobox:为组合框创建模板

时间:2017-07-29 21:20:18

标签: wpf xaml mvvm combobox .net-3.5

我有一个WPF组合框,它是从代码隐藏中填充的。

代码隐藏(xaml.cs)

namespace WpfApplication1
{
   private ObservableCollection<TransportType> transportTypes = new ObservableCollection<TransportType>();

   transportTypes.Add(new TransportType() {Icon = Properties.Resources.Air, ValueMember = "A100", DisplayMember    = "By Air" });
   transportTypes.Add(new TransportType() {Icon = Properties.Resources.Maritime, ValueMember = "M200", DisplayMember = "Maritime" });

   this.ComboBoxTransportTypes.ItemsSource = transportTypes;
}

TransportType类

namespace WpfApplication1
{
    public class TransportType
    {

        public Image Icon
        {
            get;
            set;
        }

        public string DisplayMember
        {
            get;
            set;
        }

        public string ValueMember
        {
            get;
            set;
        }
    }
}

查看

<ComboBox x:Name="ComboBoxTransportTypes"
          Grid.Column="1"               
          ItemsSource="{Binding}" 
          DisplayMemberPath="DisplayMember" 
          SelectedValuePath="ValueMember" 
          SelectionChanged="ComboBoxTransportTypes_SelectionChanged">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

现在我正在尝试应用ComboBox ItemTemplate并绑定到&#34; transportTypes&#34;采集。我希望每个组合框项目如下:

<ComboBoxItem>
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding bind-icon-here}" />
        <TextBlock Foreground="AliceBlue" 
                   VerticalAlignment="Center" 
                   Text="{Binding bind-DisplayMember-here}"/>
    </StackPanel>
</ComboBoxItem>

那么如何创建绑定到我的集合的上述组合框项目模板,以便每个项目都显示一个图标后跟一个字符串?

我在下面试过,但它不起作用。我也不知道如何将集合中的每个项目绑定到stackpanel中的图像和文本块,我已经完成如下操作,但只显示字符串而不是图标。

<ComboBox x:Name="ComboBoxTransportTypes"
          Grid.Column="1"               
          ItemsSource="{Binding}" 
          DisplayMemberPath="DisplayMember"  <-- removed from here as I cannot define DisplayMemberPath and item template at the same time.
          SelectedValuePath="ValueMember" 
          SelectionChanged="ComboBoxTransportTypes_SelectionChanged">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
    <ComboBox.ItemTemplate>
        <DataTemplate DataType="l:TransportType">
            <StackPanel Orientation="Horizontal">
                  <Image Source="{Binding Icon}" />
                  <TextBlock Foreground="AliceBlue" 
                             VerticalAlignment="Center" 
                             Text="{Binding DisplayMember}"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

另外,在MVVM中,如我在此处或从视图模型构造函数那样填充代码隐藏组合框更好吗?

3 个答案:

答案 0 :(得分:1)

问题是您在XAML和后面的代码中都设置了ItemSource。如果您从XAML中删除ItemSource="{Binding}",那么它应该可以正常工作。

如果您使用的是MVVM,则应在视图模型中填充集合,而不是在后面的代码中填充。您的代码中应该包含非常少的代码 - 只有与视图相关的内容才会出现(例如显示子窗口)。

答案 1 :(得分:0)

问题是Image.Source采用ImageSource而不是Image。改变......

<Image Source="{Binding Icon}" />

为...

 <Frame Content="{Binding Icon}"/>

然后事情就会开始发挥作用。

答案 2 :(得分:0)

您必须使用自定义模板ComboBox的底部语法

<TextBlock Text="{Binding Path=DisplayMember}"/>

<Image Source="{Binding Path=Icon}" />
  

在wpf list标签中,比如combobox,listbox,...对于像DataTemplate这样的自定义模板,你必须使用Path