【问题标题】:WPF C# MVVM program not updating ListViewWPF C# MVVM 程序不更新 ListView
【发布时间】:2014-09-24 08:18:34
【问题描述】:

我正在开发 WPF,MVVM C#​​ 简单的学习应用程序。

我的前端确实有使用元素“”的表格结构

请参阅下面的“VehicalForm.xaml”。

下面是我的视图代码以及视图模型部分。 (我只提供了必要的文件。如果您需要任何其他文件,请告诉我)

App.xaml.cs

using Seris.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;

namespace Seris
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    public void OnStartup(object sender, StartupEventArgs e)
    {
        VehicalForm vehicalForm = new VehicalForm();
        vehicalForm.DataContext = new VehicalMainViewModel();
        vehicalForm.Show();
    }
}
}

VehicalForm.xaml

<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="TextBox"  HorizontalAlignment="Left"/>
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Name="IUNO_Text" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveToList}" Content="Save" Width="66"/>
<ListView Height="294" Width="371" >
    <ListView Height="294" Width="371" ItemsSource="{Binding listItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
          <ListView.View>
            <GridView>
                <GridViewColumn Header="Vehical No" DisplayMemberBinding="{Binding VehicalNo}" />
                <GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}" />
                <GridViewColumn Header="ManufacturingDate" DisplayMemberBinding="{Binding ManufacturingDate}" />
                <GridViewColumn Header="IUNo" DisplayMemberBinding="{Binding IUNo}" />
                <GridViewColumn Header="Personnel" DisplayMemberBinding="{Binding Personnel}" />
            </GridView>
        </ListView.View>
    </ListView>
</WrapPanel> 

VehicalForm.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Seris
{

public partial class VehicalForm : Window
{
public VehicalForm()
{
    InitializeComponent();
}


}
}

VehicalMainViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;

namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
ObservableCollection<VehicalModel> listItems = new ObservableCollection<VehicalModel>();

    #region Getter-Setter
    private string _VehicalNo;

    public string VehicalNo 
    {
        get { return _VehicalNo; }
        set
        {
            if (value != _VehicalNo)
            {
                _VehicalNo = value.Trim();
                if(OnPropertyChanged("VehicalNo"))
                    listItems.Add(new VehicalModel(VehicalNo, Model, ManufacturingDate, IUNo, PersonnelName));
            }
        }
    }
    private string _Model;

    public string Model
    {
        get { return _Model; }
        set
        {
            if (value != _Model)
            {
                _Model = value.Trim();
                OnPropertyChanged("Model");
            }
        }
    }
    private DateTime _ManufacturingDate;

    public DateTime ManufacturingDate
    {
        get { return _ManufacturingDate; }
        set
        {
            if (value != _ManufacturingDate)
            {
                _ManufacturingDate = value;
                OnPropertyChanged("ManufacturingDate");
            }
        }
    }
    private string _IUNo;

    public string IUNo
    {
        get { return _IUNo; }
        set
        {
            if (value != _IUNo)
            {
                _IUNo = value.Trim();
                OnPropertyChanged("IUNo");
            }
        }
    }
    private string _PersonnelName;

    public string PersonnelName
    {
        get { return _PersonnelName; }
        set
        {
            if (value != _PersonnelName)
            {
                _PersonnelName = value.Trim();
                OnPropertyChanged("PersonnelName");
            }
        }
    } 
    #endregion

    private ICommand _saveButton_Command;

    public ICommand SaveButton_Command
    {
        get { return _saveButton_Command; }
        set { _saveButton_Command = value; }
    }

    public void SaveToList(object o1)
    {
        listItems.Add(new VehicalModel(VehicalNo,Model,ManufacturingDate,IUNo,PersonnelName));
    }
    public void RemoveFromList()
    {

    }
    public VehicalMainViewModel()
    {
        VehicalModel vm=new VehicalModel();
        SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
    }
}
}

ObservableObject.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;

namespace Seris.Models
{
public abstract class ObservableObject: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool OnPropertyChanged(string propertyName)
    {

        this.VerifyPropertyName(propertyName); 

        PropertyChangedEventHandler handler = PropertyChanged;

        if(handler!=null)
        {
            if (propertyName != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
                return true;

            }
        }
        return false;
    }

    public void VerifyPropertyName(string propertyName)
    {
        if(TypeDescriptor.GetProperties(this)[propertyName]==null)
        {
            string msg = "Invalid Property Name: " + propertyName;

            if (this.ThrowOnInvalidPropertyName)
                throw new Exception(msg);
            else
                Debug.Fail(msg);
        }
    }

    public bool ThrowOnInvalidPropertyName { get; set; }
}
}

VehicalModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Seris.Models
{
public class VehicalModel : ObservableObject
{
    #region Getter-Setter
    private string _VehicalNo;

    public string VehicalNo 
    {
        get { return _VehicalNo; }
        set
        {
            if (value != _VehicalNo)
            {
                _VehicalNo = value.Trim();
                OnPropertyChanged("VehicalNo");
            }
        }
    }
    private string _Model;

    public string Model
    {
        get { return _Model; }
        set
        {
            if (value != _Model)
            {
                _Model = value.Trim();
                OnPropertyChanged("Model");
            }
        }
    }
    private DateTime _ManufacturingDate;

    public DateTime ManufacturingDate
    {
        get { return _ManufacturingDate; }
        set
        {
            if (value != _ManufacturingDate)
            {
                _ManufacturingDate = value;
                OnPropertyChanged("ManufacturingDate");
            }
        }
    }
    private string _IUNo;

    public string IUNo
    {
        get { return _IUNo; }
        set
        {
            if (value != _IUNo)
            {
                _IUNo = value.Trim();
                OnPropertyChanged("IUNo");
            }
        }
    }
    private string _PersonnelName;

    public string PersonnelName
    {
        get { return _PersonnelName; }
        set
        {
            if (value != _PersonnelName)
            {
                _PersonnelName = value.Trim();
                OnPropertyChanged("PersonnelName");
            }
        }
    } 
    #endregion

    #region Constructor
    public VehicalModel(string VehicalNo, string Model, DateTime ManufacturingDate, string IUNo, string PersonnelName)
    {
        this.VehicalNo = VehicalNo;
        this.Model = Model;
        this.ManufacturingDate = ManufacturingDate;
        this.IUNo = IUNo;
        this.PersonnelName = PersonnelName;

    }
    public VehicalModel()
    {
        this.VehicalNo = null;
        this.Model = null;
        this.ManufacturingDate = DateTime.Now;
        this.IUNo = null;
        this.PersonnelName = null;

    } 
    #endregion

    #region Methods

    #region Validate Methods

    public bool Validate_VehicalNo()
    {
        if (matchRE(VehicalNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
            return true;
        else
            return false;
    }
    public bool Validate_Model()
    {
        if(Model!=null)
            return true;
        else
            return false;
    }
    public bool Validate_ManufacturingDate()
    {
        return true;
    }
    public bool Validate_IUNo()
    {
        if(matchRE(IUNo,"[0-9]{10}"))
            return true;
        else
            return false;
    }
    public bool Validate_PersonnelName()
    {
        if(matchRE(PersonnelName,"[A-Za-z]+"))
            return true;
        else
            return false;

    }  

    public bool matchRE(string stringToMatch, string regularExpression)
    {
        Regex regex = new Regex(@regularExpression);
        Match match = regex.Match(stringToMatch);

        if(match.Success)
            return(true);
        else
            return(false);
    }
    #endregion

    #endregion
}
}

我需要的是

1) 当我更新 VehicalNo 时,应该在表格中添加新行。

2) 如果我以后需要更新每一行的单个元素,这些元素应该在我更新后立即反映在表中,ListView 中是否有内置功能?或者我需要对单个元素(即 VehicalNo、Model、...)使用 List 并使用 ObservableObject 放入一个主 List 保持关注? 我不知道即使它被添加到列表中,并且我已经使用 ObservableObject 实现了 INotifyPropert,为什么它没有反映在前端。

请帮忙。

【问题讨论】:

  • 您需要将 VehicalForm.xaml 的 DataContext 设置为 ViewModel。并将 ListView 的ItemSource 绑定到您要显示的列表(例如ObservableCollection&lt;VehicalModel&gt; listItems)。然后将该列表视图中的每个单独列绑定到VehicalModel 的属性
  • user1:我已经正确设置了DataContext。还通过绑定到 lostItems 再次编辑了我的代码。请再次检查问题,如果不正确,请告诉我如何将 ListView 的单个属性绑定到 VehicalModel 的属性。
  • 我可以看到问题。当绑定到listItems 时,ListView 中的每一行都会获取该单个项目的数据上下文。在这个例子中,每一行都有一个VehicalModel 的数据上下文(这将有助于发布这个类)因此程序试图在你的VehicalModel 类上找到属性、VehicalNo、Model 等。我怀疑它们存在的地方。在您的输出窗口中,您可能会看到一个绑定错误,指出在对象 VehicalModel 上找不到属性 VehicalNo
  • user1:我更新了。还要求请简单解释一下这个dataContext问题,因为我是初学者。

标签: c# wpf xaml mvvm


【解决方案1】:

添加 public ObservableCollection ListItems {get{return listItems;}}

给你 VehicalMainViewModel 并将绑定更改为 ItemsSource="{Binding ListItems}"

附:您的 listItems 是私有字段。

【讨论】:

  • 这是一个很好的观察。我错过了这个错误。我建议@pratik 查看输出窗口以寻找错误的线索
  • 亲爱的朋友,你太棒了....! :) 因为声望少,不能给+1,但我这边特别虚拟。 :P Muaah...
  • 您能回答我的第二个问题吗?这对我来说也很重要。
【解决方案2】:

好的,这是第一个文本框的示例,您可以在其余部分效仿:

<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:Seris.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:VehicalMainViewModel/>
</Window.DataContext>
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="{Binding VehicalNo}"  HorizontalAlignment="Left"/>

目前我找不到任何参考资料,但我建议查看 WPF 中的 DataContext 和数据绑定

编辑

<Application x:Class="Seris.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="VehicalForm.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>

【讨论】:

  • 我还保留了 DataContext 文件供您参考。现在看到整个问题,请告诉我还剩下什么?仍然没有输出。
  • @Pratik 我会说,而不是应用程序代码中的 Startup 方法,我会在 App.Xaml 中放置一个启动 URi,详情请参阅编辑
  • 没关系。代码已经在运行,我过去已经在这两个方面工作过。请尽快找出剩余的bug,以便我给你正确的答案。
猜你喜欢
  • 2020-08-09
  • 2011-06-24
  • 2016-12-17
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多