简体   繁体   English

WPF绑定列表 <string> 到组合框

[英]WPF Binding List<string> to ComboBox

My problem is EMPTY Combobox list. 我的问题是EMPTY组合框列表。 I've walked through a lot of web site (during 3 days), but couldn't figure out it. 我已经浏览了很多网站(在3天之内),但无法弄清楚。
I've written a program that show a List of Students, clicking I can change properties them. 我编写了一个显示学生列表的程序,单击“我可以更改他们的属性”。 So, I can change succsefuly all properties except Faculty (ComboBox). 因此,我可以更改Faculty(ComboBox)以外的所有属性。
Click to see View my programm 单击以查看查看我的程序
I used MVVM.... 我使用了MVVM。
I have Class Student (Model). 我有班级学生(模特)。 Here, General is enum StudentFaculty.... 在这里,一般是枚举StudentFaculty ....

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _15._01._2018.Model
{
    public enum StudentFaculty { Programmer, SysAdministration, Designer};
    class Student : INotifyPropertyChanged
    {
        private string _name;
        private string _lastname;
        private StudentFaculty _faculty;
        private double _averageMark;

        public string Name
        {
            get { return _name; }
            set
            {
                if(_name == value) return;
                _name = value;
                OnPropertyChanged("Name");
            }
        }
        public string Lastname
        {
            get { return _lastname; }
            set
            {
                if (_lastname == value) return;
                _lastname = value;
                OnPropertyChanged("Lastname");
            }
        }
        public StudentFaculty Faculty
        {
            get { return _faculty; }
            set
            {
                if (_faculty == value) return;
                _faculty = value;
                OnPropertyChanged("Faculty");
            }
        }
        public double AverageMark
        {
            get { return _averageMark; }
            set
            {
                if (_averageMark == value) return;
                _averageMark = value;
                OnPropertyChanged("AverageMark");
            }
        }
        public Student() { }
        public Student(string name, string lastname, StudentFaculty faculty, double averageMark)
        {
            Name = name;
            Lastname = lastname;
            Faculty = faculty;
            AverageMark = averageMark;
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

Class ApplicationViewModel. 类ApplicationViewModel。 Here, I make List (Faculties) from enum in Constructor, also SelectedFaculty... 在这里,我从构造函数中的枚举中创建列表(系),也选择了系...

using _15._01._2018.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _15._01._2018.ViewModel
{
    class ApplicationViewModel : INotifyPropertyChanged
    {
        private Student _selectedStudent;
        private string _selectedFaculty;
        public ObservableCollection<Student> Students { get; set; }
        public List<string> Faculties { get; set; }
        public Student SelectedStudent
        {
            get { return _selectedStudent; }
            set
            {
                if (_selectedStudent == value) return;
                _selectedStudent = value;
                OnChangedProperty("SelectedStudent");
            }
        }
        public string SelectedFaculty
        {
            get { return _selectedFaculty; }
            set
            {
                if (_selectedFaculty == value) return;
                _selectedFaculty = value;
                OnChangedProperty("SelectedFaculty");
            }
        }
        public ApplicationViewModel()
        {
            Students = new ObservableCollection<Student>
            {
                new Student("Vova", "Zyabkin", StudentFaculty.Programmer, 9.4),
                new Student("Vadym", "Lazariev", StudentFaculty.Programmer, 9),
                new Student("SvEta", "Belyaeva", StudentFaculty.Designer, 9.8),
                new Student("Vova", "Skachkov", StudentFaculty.SysAdministration, 8.7)
            };
            Faculties = new List<string>(Enum.GetNames(typeof(StudentFaculty)));
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnChangedProperty(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
} 

XAML XAML

<Window x:Class="_15._01._2018.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_15._01._2018"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="14" />
        </Style>
        <Style TargetType="TextBox">
            <Setter Property="FontSize" Value="14" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding Students}" SelectedItem="{Binding SelectedStudent}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding Path=Name}"></TextBlock>
                        <TextBlock Text="{Binding Path=Lastname}"></TextBlock>
                        <!--<TextBlock Text="{Binding Path=Faculty}"></TextBlock>-->
                        <TextBlock Text="{Binding Path=AverageMark}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Grid Grid.Column="1">
            <StackPanel DataContext="{Binding SelectedStudent}">
                <TextBlock Text="D A T A"></TextBlock>
                <TextBlock Text="Name:"></TextBlock>
                <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
                <TextBlock Text="Lastname:"></TextBlock>
                <TextBox Text="{Binding Lastname, UpdateSourceTrigger=PropertyChanged}"></TextBox>
                <TextBlock Text="Faculty:"></TextBlock>
                <ComboBox ItemsSource="{Binding Faculties}" SelectedItem="{Binding SelectedFaculty}">

                </ComboBox>
                <TextBlock Text="Average Mark:"></TextBlock>
                <TextBox Text="{Binding AverageMark, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

I have idea to create a Class with String property Faculty, but it's like with ListBox and Student. 我有创建带有字符串属性Faculty的类的想法,但它类似于ListBox和Student。

To start off with, the DataContext for your ComboBox is set to the SelectedStudent, not the ApplicationViewModel (see the parent StackPanel). 首先,将ComboBox的DataContext设置为SelectedStudent,而不是ApplicationViewModel(请参见父StackPanel)。 Second, you have the Faculties property returning a list of String, but the Student class has a property of StudentFaculty (binding for SelectedValue won't work). 其次,您具有Faculties属性,它返回String列表,但是Student类具有StudentFaculty属性(对SelectedValue的绑定将不起作用)。

Try the following: 请尝试以下操作:

Models/ViewModels: 型号/的ViewModels:

class ApplicationViewModel : INotifyPropertyChanged
{
    private Student _selectedStudent;
    private StudentFaculty _selectedFaculty;
    public ObservableCollection<Student> Students { get; set; }
    public ObservableCollection<StudentFaculty> Faculties { get; set; }
    public Student SelectedStudent
    {
        get => _selectedStudent;
        set
        {
            if (_selectedStudent == value) return;
            _selectedStudent = value;
            OnChangedProperty("SelectedStudent");
        }
    }
    public StudentFaculty SelectedFaculty
    {
        get => _selectedFaculty;
        set
        {
            if (_selectedFaculty == value) return;
            _selectedFaculty = value;
            OnChangedProperty("SelectedFaculty");
        }
    }
    public ApplicationViewModel()
    {
        Students = new ObservableCollection<Student>
        {
            new Student("Vova", "Zyabkin", StudentFaculty.Programmer, 9.4),
            new Student("Vadym", "Lazariev", StudentFaculty.Programmer, 9),
            new Student("SvEta", "Belyaeva", StudentFaculty.Designer, 9.8),
            new Student("Vova", "Skachkov", StudentFaculty.SysAdministration, 8.7)
        };
        Faculties = new ObservableCollection<StudentFaculty>(Enum.GetValues(typeof(StudentFaculty)).OfType<StudentFaculty>());
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnChangedProperty(string property) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

public enum StudentFaculty { Programmer, SysAdministration, Designer };
class Student : INotifyPropertyChanged
{
    private string _name;
    private string _lastname;
    private StudentFaculty _faculty;
    private double _averageMark;

    public string Name
    {
        get => _name;
        set
        {
            if (_name == value) return;
            _name = value;
            OnPropertyChanged("Name");
        }
    }
    public string Lastname
    {
        get => _lastname;
        set
        {
            if (_lastname == value) return;
            _lastname = value;
            OnPropertyChanged("Lastname");
        }
    }
    public StudentFaculty Faculty
    {
        get => _faculty;
        set
        {
            if (_faculty == value) return;
            _faculty = value;
            OnPropertyChanged("Faculty");
        }
    }
    public double AverageMark
    {
        get => _averageMark;
        set
        {
            if (_averageMark == value) return;
            _averageMark = value;
            OnPropertyChanged("AverageMark");
        }
    }
    public Student() { }
    public Student(string name, string lastname, StudentFaculty faculty, double averageMark)
    {
        Name = name;
        Lastname = lastname;
        Faculty = faculty;
        AverageMark = averageMark;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string property) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}

XAML : XAML

<Window x:Class="WpfApp4.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:converters="clr-namespace:WpfApp4.Views.Converters"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:viewModels="clr-namespace:WpfApp4.ViewModels"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <viewModels:ApplicationViewModel />
</Window.DataContext>
<Window.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="FontSize" Value="14" />
    </Style>
    <Style TargetType="TextBox">
        <Setter Property="FontSize" Value="14" />
    </Style>
    <CollectionViewSource x:Key="Faculties" Source="{Binding Faculties}"></CollectionViewSource>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ListBox ItemsSource="{Binding Students}" SelectedItem="{Binding SelectedStudent}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Path=Name}"></TextBlock>
                    <TextBlock Text="{Binding Path=Lastname}"></TextBlock>
                    <!--<TextBlock Text="{Binding Path=Faculty}"></TextBlock>-->
                    <TextBlock Text="{Binding Path=AverageMark}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Grid Grid.Column="1">
        <StackPanel DataContext="{Binding SelectedStudent}">
            <TextBlock Text="D A T A"></TextBlock>
            <TextBlock Text="Name:"></TextBlock>
            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            <TextBlock Text="Lastname:"></TextBlock>
            <TextBox Text="{Binding Lastname, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            <TextBlock Text="Faculty:"></TextBlock>
            <ComboBox ItemsSource="{Binding Source={StaticResource Faculties}}" SelectedValue="{Binding Faculty, Mode=TwoWay}">

            </ComboBox>
            <TextBlock Text="Average Mark:"></TextBlock>
            <TextBox Text="{Binding AverageMark, UpdateSourceTrigger=PropertyChanged}"></TextBox>
        </StackPanel>
    </Grid>
</Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM