簡體   English   中英

WPF綁定到屬性列表未更新

[英]WPF Binding to property list not updating

救命。 我已經使用Google和stackoverflow搜索欄搜索了一周,卻沒有找到答案。

因此,我有一個名為Student的類,其屬性為字符串名稱,字符串地址,DoB DateofBirth和列表得分。 還有一個Student類的ViewModel類。

public partial class StudentWindow : Window
{
    public class DoB
    {
        public int Day { get; set; }
        public int Month { get; set; }
        public int Year { get; set; }
        public DoB(int day, int month, int year)
        {
            Day = day;
            Month = month;
            Year = year;
        }
        public override string ToString()
        {
            return Day + "/" + Month + "/" + Year;
        }
    }
    public class Student
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public DoB DateOfBirth { get; set; }
        public List<int> Score { get; set; }
    }
    public class ViewModel : INotifyPropertyChanged
    {
        private Student entry;
        public event PropertyChangedEventHandler PropertyChanged;
        public void Notify(string Property)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(Property));
        }
        public string Name
        {
            get { return entry.Name; }
            set { entry.Name = value; Notify("Name"); }
        }
        public string Address
        {
            get { return entry.Address; }
            set { entry.Address = value; Notify("Address"); }
        }
        public string DateOfBirth
        {
            get { return entry.DateOfBirth.ToString(); }
            set
            {
                var p = value.Split('/');
                int d = 1, m = 1, y = 1;
                bool pass = int.TryParse(p[0], out d) && int.TryParse(p[1], out m) && int.TryParse(p[2], out y);
                if (pass)
                {
                    entry.DateOfBirth = new DoB(d, m, y);
                    Notify("DateOfBirth");
                }
                else
                    throw new InvalidCastException();
            }
        }
        public List<string> Score
        {
            get { return entry.Score.Select(sc => "" + sc).ToList(); }
            set { entry.Score = value.Select(va => int.Parse(va)).ToList(); Notify("Score"); }
        }
        public ViewModel(Student entry)
        {
            this.entry = entry;
        }
    }
    public ObservableCollection<ViewModel> entry { get; set; }
    public StudentWindow()
    {
        InitializeComponent();

        entry = new ObservableCollection<ViewModel>();
        entry.Add(new ViewModel(new Student() { Name = "First People", Address = "Earth", DateOfBirth = new DoB(13, 11, 1996), Score = new List<int>(new int[] { 100, 90, 100, 90 }) }));
        entry.Add(new ViewModel(new Student() { Name = "Second People", Address = "Moon", DateOfBirth = new DoB(13, 11, 1995), Score = new List<int>(new int[] { 90, 80, 100, 100 }) }));

        DataContext = this;
    }
}

XAML是

<Grid>
    <DataGrid x:Name="dataGridStudent" ItemsSource="{Binding entry}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="210" Width="572"/>
    <DataGrid x:Name="dataGridStudentScore" ItemsSource="{Binding ElementName=dataGrid, Path=SelectedItem.Score}" HorizontalAlignment="Left" Margin="10,242,0,0" VerticalAlignment="Top" Height="218" Width="572" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

對於dataGridStudent一切正常。

但是dataGridStudentScore僅顯示值,而無法編輯值。 我必須設置Binding Path =。 ,否則會拋出Path或Xpath異常。

請為您提供任何解決方案的幫助。 我是新手,請告訴我我的做法是否有問題。 提前致謝。

忽略對MVVM體系結構的困惑理解。 學生分數不可編輯的原因是您嘗試將值類型變量綁定到DataGridTextColumn。 我不確定DependencyProperty綁定的后台實現,但是我可以想象沒有引用可以綁定到該更新中,因為它只是一個值類型變量。

我對wpf也不抱期望,但是我將在下面實現同樣的事情。

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Score : ViewModelBase
{
    public int Value { get; set; }
}

public class Student : ViewModelBase
{
    public string Name { get; private set; }
    public string Address { get; private set; }
    public DateTime Dob { get; private set; }

    public ObservableCollection<Score> Scores { get; set; }

    public Student(string name, string address, DateTime dob)
    {
        Name = name;
        Address = address;
        Dob = dob;

        Scores = new ObservableCollection<Score>();
    }
} 

public class StudentViewModel : ViewModelBase
{
    public ObservableCollection<Student> Students { get; private set; }

    public StudentViewModel()
    {
        Students = new ObservableCollection<Student>
        {
            new Student("Student A", "A Address", DateTime.Now)
            {
                Scores = new ObservableCollection<Score>
                {
                    new Score { Value = 80 }, 
                    new Score { Value = 85 }, 
                    new Score { Value = 90 }, 
                }
            },
            new Student("Student B", "B Address", DateTime.Now)
            {
                Scores = new ObservableCollection<Score>
                {
                    new Score { Value = 70 }, 
                    new Score { Value = 75 }, 
                    new Score { Value = 60 }, 
                }
            }
        };
    }

    private Student _selectedStudent;        
    public Student SelectedStudent
    {
        get { return _selectedStudent; }
        set 
        {
            _selectedStudent = value;
            OnPropertyChanged("SelectedStudentScores");
        }
    }

    public ObservableCollection<Score> SelectedStudentScores
    {
        get
        {
            if (_selectedStudent == null) return null;
            return _selectedStudent.Scores;
        }
    }

    public Score SelectedScore { get; set; }
}

<Window x:Class="StudentScoreWpfProj.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:studentScoreWpfProj="clr-namespace:StudentScoreWpfProj"
    mc:Ignorable="d"
    d:DataContext="{d:DesignInstance Type=studentScoreWpfProj:StudentViewModel,IsDesignTimeCreatable=True}"        
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <DataGrid ItemsSource="{Binding Students}" AutoGenerateColumns="False"
              SelectedItem="{Binding SelectedStudent}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=OneWay}" />
            <DataGridTextColumn Header="Address" Binding="{Binding Address, Mode=OneWay}" />
            <DataGridTextColumn Header="Birth" Binding="{Binding Dob, Mode=OneWay, StringFormat={}{0:MM/dd/yyyy}}" />
        </DataGrid.Columns>
    </DataGrid>

    <DataGrid Grid.Row="1" ItemsSource="{Binding SelectedStudentScores}"
              SelectedItem="{Binding SelectedScore}">
    </DataGrid>
</Grid>

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new StudentViewModel();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM