为ComboBox设置标签功能

时间:2013-03-21 16:24:23

标签: c# wpf combobox

有没有办法为放置在组合框中的项目使用标签功能?

目前,它使用ToString()来获取标签。例如,假设您有一个由ComboBox类型的列表对象支持的Person

namespace WpfApplication1 {
    public class Person {

        public string fname { get; set; }

        public string mname { get; set; }

        public string lname { get; set; }

        public Person(string fname, string mname, string lname) {
            this.fname = fname;
            this.mname = mname;
            this.lname = lname;
        }

        public override string ToString() {
            return this.lname +", " + this.fname + " "+ this.mname;
        }
    }
}

但是现在你希望每个人的文字在某些地方只有this fname + " "+ this.mname[0]+" "+this.lname。理想情况下,我希望能够在后备XAML cs文件中添加一个方法,如:

public string GetLabel(Person item) {
    return item.fname + " " + item.mname[0] + " " + item.lname;
}

然后以某种方式将它指向cs文件中方法的ComboBox。

<小时/> 这是一个示例XAML文件和XAML.cs,如果有任何帮助:
MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="250">
    <Grid>
        <ComboBox x:Name="items" Height="22" Width="200" ItemsSource="{Binding}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;

namespace WpfApplication1 {
   public partial class MainWindow : Window {

        public List<Person> persons { get; set; }

        public MainWindow() {
            InitializeComponent();
            this.persons = new List<Person>();
            persons.Add(new Person("First", "Middle", "Last"));
            persons.Add(new Person("John", "Jacob", "Jingleheimer"));
            persons.Add(new Person("First", "Middle", "Last"));

            this.items.DataContext = this.persons;
        }


        public string GetLabel(Person item) {
            return item.fname + " " + item.mname[0] + " " + item.lname;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你应该看一下使用ViewModel来更直接地做到这一点,但如果你想做你要求的事情,你可以在你的ComboBox上绑定的Person类上创建另一个属性

public class Person 
{
    public string fname { get; set; }
    public string mname { get; set; }
    public string lname { get; set; }

    public string FullName
    {
        get
        {
            return item.fname + " " + item.mname[0] + " " + item.lname;
        }
    }

    public Person(string fname, string mname, string lname) 
    {
        this.fname = fname;
        this.mname = mname;
        this.lname = lname;
    }
}

然后你可以使用这个XAML:

<ComboBox x:Name="items" Height="22" Width="200" ItemsSource="{Binding} DisplayMemberPath="FullName"/>

我再次建议您了解有关MVVM的更多信息。

我希望这有帮助。


修改

好的,你问过我是否可以告诉你如何使用MVVM做到这一点,所以就这样吧。

首先我们有Person类,这是我们的模型(我重命名属性并添加了Id字段,因为我可以)

public class Person
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }

    public Person()
    {
        Id = Guid.NewGuid();
    }

    public Person(string firstName, string middleName, string lastName)
    {
        Id = Guid.NewGuid();
        FirstName = firstName;
        MiddleName = middleName;
        LastName = lastName;
    }
}

请注意,我没有使用FullName属性污染我的模型,因为这纯粹是为了显示,所以我们将它放在ViewModel中。

这是PersonViewModel(请注意,本例中的ViewModelBase只是实现INotifyPropertyChanged的基类):

public class PersonViewModel : ViewModelBase
{
    private Person person { get; set; }

    public Guid Id { get { return person.Id; } }

    public String FirstName
    {
        get { return person.FirstName; }
        set
        {
            if (person.FirstName != value)
            {
                person.FirstName = value;
                RaisePropertyChanged("FirstName");
            }
        }
    }

    public string MiddleName
    {
        get { return person.MiddleName; }
        set
        {
            if (person.MiddleName != value)
            {
                person.MiddleName = value;
                RaisePropertyChanged("MiddleName");
            }
        }
    }

    public string LastName
    {
        get { return person.LastName; }
        set
        {
            if (person.LastName != value)
            {
                person.LastName = value;
                RaisePropertyChanged("LastName");
            }
        }
    }

    public string FullName { get { return LastName + ", " + FirstName + " " + MiddleName; } }

    public PersonViewModel()
    {
        person = new Person();
    }

    public PersonViewModel(Person inPerson)
    {
        person = inPerson;
    }
}

它基本上使用提升PropertyChanged通知的属性包装我们的Person类(如果要在属性更改时更新屏幕,则需要)。它还添加了新的FullName属性。

接下来我们有一个MainViewModel,因为我不想将代码放入MainWindow的Code Behind页面。它只是声明我们的List<PersonViewModel>并填充它。

public class MainViewModel : ViewModelBase
{
    public List<PersonViewModel> People { get; set; }

    public MainViewModel()
    {
        // Get the people list from your data provider (in this case returns IEnumerable<Person>)
        var peopleList = DataProvider.GetPeople();

        // Wrap each person in a PersonViewModel to make them more UI friendly
        People = peopleList.Select(p => new PersonViewModel(p)).ToList();
    }
}

最后,我们的MainWindow上有ComboBox

<Window x:Class="MVVM_Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:MVVM_Sample.ViewModels"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{DynamicResource ViewModel}">
<Window.Resources>
    <vm:MainViewModel x:Key="ViewModel" />
</Window.Resources>
<Grid>
    <ComboBox ItemsSource="{Binding People}" DisplayMemberPath="FullName" SelectedValuePath="Id" Height="22" Width="200" />
</Grid>
</Window>

请注意,我在参考资料中声明了MainViewModel的实例,并将其设置为Window的DataContext。这使得我的Binding语句在MainViewModel中查找值。

我知道这对于这样一个简单的例子似乎有点长篇大论,但是当事情开始变得复杂并且它有助于保持所需的关注点分离时,它会更有意义。 MVVM和XAML都是很棒的工具,但是有一个学习曲线。