简体   繁体   中英

WPF ComboBox Throwing an Exception

Below are my files. While I run the command because of ComboBox, it is throwing some weird runtime exception as below.

在此处输入图片说明

Without ComboBox it runs well.

How can I improve my code such that it starts working with ComboBox?

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="500" Width="600">
<Control>
    <Control.Template>
        <ControlTemplate>
            <WrapPanel Orientation="Vertical" Margin="10 " >
                <Label Content="Vehical No" HorizontalAlignment="Left"/>
                <TextBox Name="VehicalNo_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding VehicalNo}"  HorizontalAlignment="Left" />
                <Label Content="Model" HorizontalAlignment="Left"/>
                <TextBox Name="Model_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding Model}" HorizontalAlignment="Left" />
                <Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
                <DatePicker Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, Mode=TwoWay}"/>
                <Label Content="IU No" HorizontalAlignment="Left"/>
                <TextBox Height="23" Width="80" Name="IUNO_Text" TextWrapping="Wrap" Text="{Binding IUNo}" HorizontalAlignment="Left"/>
                <Label Content="Personnel" HorizontalAlignment="Left"/>
                <ComboBox Name="Personnel_Combo" Loaded="{Binding Personnel_Combo_Loaded}" HorizontalAlignment="Left" Width="116"/>
                <Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
                <Button Name="Save_Button" Command="{Binding SaveButton_Command}" Content="Save" Width="66"/>
                <Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="41" Width="137"/>
                <ListView Name ="Grid" Height="294" Width="371" >
                    <DataGrid Name="DG" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}" SelectionUnit="Cell" GridLinesVisibility="None" IsReadOnly="True" AutoGenerateColumns="False" BorderThickness="0">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}" />
                            <DataGridTextColumn Header="Model" Binding="{Binding Model}" />
                            <DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
                            <DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
                            <DataGridTextColumn Header="Personnel" Binding="{Binding Personnel}" />

                        </DataGrid.Columns>

                    </DataGrid>
                </ListView>
                <Label Name="Notification" Content="hjgj"/>

            </WrapPanel>
            <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding IsMouseOver, ElementName=Grid}" Value="true">
                    <Setter Property="Content" TargetName="Notification" Value="abc"/>


                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Control.Template>
</Control>
</Window>

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;
using System.Windows;
using System.Windows.Controls;

namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
public ObservableCollection<VehicalModel> _listItems ;

private string _erroMesage;

public string ErrorMessage
{
    get { return _erroMesage; }
    set { _erroMesage = value; OnPropertyChanged("ErrorMessage"); }
}

public ObservableCollection<VehicalModel> ListItems
{
    get { return _listItems; }
    set
    {
        if (!value.Equals( _listItems))
        {
            _listItems = value;
        }
    }
}
    #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 ObservableCollection<string> _PersonnelName;

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

    private ICommand _saveButton_Command;

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



    public void Personnel_Combo_Loaded(object sender, RoutedEventArgs e)
    {
        var Personnel_ComboBox = sender as ComboBox;
        Personnel_ComboBox.ItemsSource = PersonnelName;
    }
    public void SaveToList(object o1)
    {
        ErrorMessage="";
        try
        {
            _listItems.Add(new VehicalModel(VehicalNo, Model, ManufacturingDate, IUNo, PersonnelName));
        }
        catch(Exception ex)
        {
            ErrorMessage = ex.Message;
        }
    }
    public void RemoveFromList()
    {

    }
    public VehicalMainViewModel()
    {
        ListItems = new ObservableCollection<VehicalModel>();
        PersonnelName = new ObservableCollection<string>() { "sd", "ad", "ad" };
        ErrorMessage = "";
        VehicalModel vm=new VehicalModel();
        SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));

    }
}
}

VehicalModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
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 ObservableCollection<string> _PersonnelName;

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

    #region Constructor
    public VehicalModel(string VehicalNo, string Model, DateTime? ManufacturingDate, string IUNo, ObservableCollection<string> PersonnelName)
    {
        this.VehicalNo = VehicalNo;
        this.Model = Model;
        this.ManufacturingDate = ManufacturingDate;
        this.IUNo = IUNo;
        this.PersonnelName = PersonnelName;
        if(!(Validate_VehicalNo() && Validate_Model() && Validate_ManufacturingDate() && Validate_IUNo()))
            throw(new Exception("Invalid Data"));
    }
    public VehicalModel()
    {
        VehicalNo = null;
        Model = null;
        ManufacturingDate = null;
        IUNo = null;
        PersonnelName = new ObservableCollection<string>();

    } 
    #endregion

    #region Methods

    #region Validate Methods

    public bool Validate_VehicalNo()
    {
        if (VehicalNo == null)
            return false;
        if (matchRE(VehicalNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
            return true;
        else
            return false;
    }
    public bool Validate_Model()
    {
        if (Model == null)
            return false;
        if(Model!=null || Model.Length==0)
            return true;
        else
            return false;
    }
    public bool Validate_ManufacturingDate()
    {
        if (ManufacturingDate == null)
            return false;
        return true;
    }
    public bool Validate_IUNo()
    {
        if (IUNo == null || Model.Length==0)
            return false;
        if(matchRE(IUNo,"[0-9]{10}"))
            return true;
        else
            return false;
    }
    public bool Validate_PersonnelName()
    {
        if (PersonnelName == null)
            return false;
        //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
}
}

You cannot bind to an event, and FrameworkElement.Loaded is an event.

What you can do is create an ICommand (instead of an event handler) and look at some sort of Event To Command solution.


After reading what the event you are attempting to do is actually doing, I would actually recommend that you instead bind your collection to the ItemsSource property instead of trying to set the items source after the control is loaded. If you only want to bind it one time, you can always use the BindingMode.OneTime setting.

<ComboBox ItemsSource="{Binding Path=PersonnelName}" />

You cannot bind method to Loaded event in ViewModel. Move the event handler in code behind and change your XAML to this:

<ComboBox Name="Personnel_Combo" Loaded="Personnel_Combo_Loaded" 
          HorizontalAlignment="Left" Width="116"/>

Also accessing UI element in ViewModel is first and foremost violation of MVVM.


Moreover in loaded handler you are setting ItemSource, so get rid of Loaded handler and bind directly to the property in XAML:

<ComboBox Name="Personnel_Combo" ItemsSource="{Binding PersonnelName}" 
          HorizontalAlignment="Left" Width="116"/>

In case you intend to do much more in the event handler instead of setting ItemsSource, you have to create an ICommand in ViewModel and bind to the event using interactivity triggers. Check out the answer here to get you started on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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