ComboBox不会选择ViewModel提供的任何项目

时间:2014-09-20 00:53:08

标签: c# wpf xaml

假设我的名为person的Model类看起来像下面的代码:

public class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
    public Gender Gender { get; set; }
}

Person类中使用的Gender类看起来像:

public class Gender
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string ImageData { get; set; }
}

现在在一个名为EditView的视图中,我试图显示当前所选人员的信息:

<Page ...............>

    <Page.DataContext>
        <vm:EditViewModel />
    </Page.DataContext>

    <Grid DataContext="{Binding CurrentPerson}">

        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>

        <TextBox Text="{Binding Name}" />

        <ComboBox Grid.Row="1"
                  ItemsSource="{Binding DataContext.Genders, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}" 
                  SelectedItem="{Binding Gender}">

            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Padding="6"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>

            <ComboBox.ItemContainerStyle>
                <Style TargetType="{x:Type ComboBoxItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Grid x:Name="gd" TextElement.Foreground="Black">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto" />
                                        <ColumnDefinition Width="*" />
                                    </Grid.ColumnDefinitions>
                                    <Path Grid.Column="0" Data="{Binding ImageData}" Stretch="Uniform" Fill="Black" Width="24" Height="24" Margin="4" RenderTransformOrigin="0.5,0.5" />
                                    <TextBlock Grid.Column="1" Text="{Binding Name}" Padding="6"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="ComboBoxItem.IsSelected" Value="True">
                                        <Setter TargetName="gd"  Property="Background" Value="#FF4CC4F6"></Setter>
                                        <Setter TargetName="gd"  Property="TextElement.Foreground" Value="White"></Setter>
                                    </Trigger>
                                    <Trigger Property="ComboBoxItem.IsMouseOver" Value="True">
                                        <Setter TargetName="gd"  Property="Background" Value="#FF84CDFA"></Setter>
                                        <Setter TargetName="gd"  Property="TextElement.Foreground" Value="White"></Setter>
                                    </Trigger>
                                    <Trigger Property="ComboBoxItem.IsHighlighted" Value="True">
                                        <Setter TargetName="gd"  Property="Background" Value="LightSkyBlue"></Setter>
                                        <Setter TargetName="gd"  Property="TextElement.Foreground" Value="Black"></Setter>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ComboBox.ItemContainerStyle>

        </ComboBox>

    </Grid>

</Page>

EditViewModel.cs代码:

public class EditViewModel : ViewModelBase
{
    public EditViewModel()
    {
        Genders = new ObservableCollection<Gender>(
                                                        from gender in XDocument.Load(DirectoryPaths.DataDirectory + @"Basic\Genders.xml")
                                                                                .Element("Genders").Elements("Gender")
                                                        select new Gender
                                                                    {
                                                                        Id = Convert.ToInt32(gender.Attribute("Id").Value),
                                                                        Name = gender.Element("Name").Value,
                                                                        ImageData = gender.Element("ImageData").Value
                                                                    }
                                                  );
    }

    private ObservableCollection<Gender> _genders;
    public ObservableCollection<Gender> Genders
    {
        get
        {
            return _genders;
        }
        set
        {
            _genders = value;
            NotifyPropertyChanged("Genders");
        }
    }

    private Person _currentPerson;
    public Person CurrentPerson
    {
        get
        {
            return _currentPerson;
        }
        set
        {
            _currentPerson = value;
            NotifyPropertyChanged("CurrentPerson");
        }
    }
}

我添加了viewmodel的相关代码。当显示EditView时,属性CurrentPerson有一个人。但是在ComboBox中我没有默认选择。我可以手动选择值。但是当EditView加载时,我无法说出该人的性别,因为它没有显示为ComboBox的SelectedItem。

1 个答案:

答案 0 :(得分:3)

您遇到了一个非常常见的问题,两个相同的Gender个对象并不相同!

ComboBox看到绑定的选定项目,但没有看到匹配的项目(实际上,它没有看到匹配的参考)所以它没有&#39 ; t选择任何东西。

要解决此问题,Gender需要覆盖Object.EqualsMSDN)和Object.GetHashCodeMSDN)。根据此article,实施IEquatable也将有效。