Casting Variables / Objects时的RunTime异常

时间:2014-08-08 03:02:02

标签: c# wpf mvvm runtime-error

我在VehicleMainModel类中有变量PersonnelName。 我想从PersonnelMainViewModel的对象PersonnelObject获取引用。

运行后,我的代码行抛出Typecast异常:

PersonnelName =(bservableCollection)(PersonnelObject.Select(x => x.Name));

我不明白如何解决这个问题。即使双方都是字符串列表,它不起作用。供你参考,我在这里附上我的两个课程。

请为此提供工作线。

我已经为你截断了不必要的代码。

enter image description here

vehicleMainViewModel

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;
using System.Threading;
using System.ComponentModel;
using Seris.Views;

namespace Seris.ViewModels
{
public class VehicleMainViewModel : ObservableObject
{

    #region Getters-Setters

//静态变量......

    private static VehicleMainViewModel _Instance;
    public static VehicleMainViewModel getInstance
    {
        get
        {
            if(_Instance==null)
            {
                _Instance = new VehicleMainViewModel();
            }
            return _Instance;
        }
    }

    private static AddVehicle _addVehicle;
    public static AddVehicle addVehicle
    {
        get
        {
            return _addVehicle;
        }
        set
        {
            _addVehicle = value;
        }
    }

//非静态变量......

   // Error Components

    . . .

    private string _PersonnelNameSelected;
    public string PersonnelNameSelected
    {
        get { return _PersonnelNameSelected; }
        set
        {
            if (value == null || (!value.Equals(_PersonnelNameSelected)))
            {
                _PersonnelNameSelected = value;
                EditText = _PersonnelNameSelected;
                OnPropertyChanged("PersonnelNameSelected");
                validateSpecificData(5);
            }
        }
    }


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

    private ObservableCollection<PersonnelModel> _PersonnelObject;
    public ObservableCollection<PersonnelModel> PersonnelObject
    {
        get { return _PersonnelObject; }
        set
        {
            if (value != _PersonnelObject)
            {
                _PersonnelObject = value;
                OnPropertyChanged("PersonnelObject");
            }
        }
    }

    private ObservableCollection<VehicleModel> _listItems;
    public ObservableCollection<VehicleModel> ListItems
    {
        get { return _listItems; }
        set
        {
            if (value == null || (!value.Equals(_listItems)))
            {
                _listItems = value;
            }
        }
    }

    // Other Variables

//静态方法......

    public static void showMessage(string message)
    {
        MessageBox.Show(message);
    } 

//非静态方法......

    . . .

    public void clearAllData()
    {
        VehicleNo=null;
        Model=null;
        ManufacturingDate=null;
        IUNo=null;
        PersonnelNameSelected=null;

        VehicleNo_Error = "";
        Model_Error = "";
        ManufacturingDate_Error = "";
        IUNo_Error = "";
        Personnel_Error= "";
    }
    #endregion

    #region Constructors

    public VehicleMainViewModel()
    {
        // Initialization

        ListItems = new ObservableCollection<VehicleModel>();
        PersonnelObject = PersonnelMainViewModel.getInstance.Personnel_List;

//This line gives error//
        PersonnelName = (ObservableCollection<string>) (PersonnelObject.Select(x => x.Name));

        // Setting Flags
        ErrorMessage = "";
        IsEnableReplaceButton = false;


        // Commands Initialization

        . . .
    } 

    #endregion


}
}

PersonnelMainViewModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Markup;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Documents;
using System.Windows.Controls.Primitives;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Diagnostics;
using System.Security;
using System.Collections.ObjectModel;

using Seris.Models;
using Seris.Views;
using Seris.ViewModels;
using Seris.Properties;
using Seris.Commands;



namespace Seris.ViewModels
{
public class PersonnelMainViewModel :ObservableObject 
{
    public ObservableCollection<PersonnelModel> Personnel_List;
    private ObservableCollection<PersonnelModel> Personnel_copy;
    public PersonnelModel model = new PersonnelModel();
    public List<string> MyString;
    public ICommand EditCommand;
    public ICommand AddCommand;
    public bool isRemove;
    public static ObservableCollection<string> PersonNameList_Updating;

    private static PersonnelMainViewModel _Instance;
    public static PersonnelMainViewModel getInstance
    {
        get
        {
            if (_Instance == null)
            {
                _Instance = new PersonnelMainViewModel();
            }
            return _Instance;
        }
    }

    public PersonnelMainViewModel()
    {

        MyString = new List<string>();
        Personnel_copy = new ObservableCollection<PersonnelModel>();
       isRemove = false;
       Personnel_List = new ObservableCollection<PersonnelModel>
        {
             new PersonnelModel{ID=Guid.NewGuid(),Name="Mr.Joe",Gender="Male",Hospital="Poly Clinic",EMPID="abc 123",Capabilities="123",Position="Assistant",Title="Test",Status="General",ICNumber="IC 123",Roles="Test"},
             new PersonnelModel{ID=Guid.NewGuid(),Name="Su Su",Gender="Female",Hospital="Clementi Clinic",EMPID="abc 1234",Capabilities="1234",Position="Security",Title="Test",Status="General",ICNumber="IC 1234",Roles="Test"},
              new PersonnelModel{ID=Guid.NewGuid(),Name="Ms Tan",Gender="Female",Hospital="Bishan Clinic",EMPID="abc 1235",Capabilities="1235",Position="HR",Title="Test",Status="General",ICNumber="IC 1235",Roles="Test"},
        };

       Personnel_copy = new ObservableCollection<PersonnelModel>
    {
        new PersonnelModel{ID=Guid.NewGuid(),Name="Mr.Joe",Gender="Male",Hospital="Poly Clinic",EMPID="abc 123",Capabilities="123",Position="Assistant",Title="Test",Status="General",ICNumber="IC 123",Roles="Test"},
        new PersonnelModel{ID=Guid.NewGuid(),Name="Su Su",Gender="Female",Hospital="Clementi Clinic",EMPID="abc 1234",Capabilities="1234",Position="Security",Title="Test",Status="General",ICNumber="IC 1234",Roles="Test"},
        new PersonnelModel{ID=Guid.NewGuid(),Name="Ms Tan",Gender="Female",Hospital="Bishan Clinic",EMPID="abc 1235",Capabilities="1235",Position="HR",Title="Test",Status="General",ICNumber="IC 1235",Roles="Test"},
    };

        PersonNameList_Updating = new ObservableCollection<string> (Personnel_List.Select(x => x.Name));
        _hos = new ObservableCollection<string> (Personnel_List.Select(x=>x.Hospital) );

        EditCommand = new RelayCommand(Edit);
        AddCommand = new RelayCommand(Add);
        Removecommand = new RelayCommand(Remove);
        SearchCommand = new RelayCommand(search);

        //string[] textList = this.FindResource("Personnel_vm") as string[];
        //ICollectionView view = CollectionViewSource.GetDefaultView(textList);
        //new TextSearchFilter(view, this.txtSearch);


       }


   . . .

    #endregion

   . . .
    }
}

VehicleModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Seris.ViewModels;

namespace Seris.Models
{
public class VehicleModel : ObservableObject
{
    #region Getters-Setters

    private Guid? _UniqueNo;
    public Guid? UniqueNo
    {
        get { return _UniqueNo; }
        set
        {
            if (value != _UniqueNo)
            {
                _UniqueNo = value;
                OnPropertyChanged("UniqueNo");

            }
        }
    }

    private string _VehicleNo;
    public string VehicleNo 
    {
        get { return _VehicleNo; }
        set
        {
            if (value != _VehicleNo)
            {
                _VehicleNo = value.Trim();
                OnPropertyChanged("VehicleNo");
            }
        }
    }

    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 _PersonnelNameSelected;
    public string PersonnelNameSelected
    {
        get { return _PersonnelNameSelected; }
        set
        {
            if (value != _PersonnelNameSelected)
            {
                _PersonnelNameSelected = value;
                OnPropertyChanged("PersonnelNameSelected");
            }
        }
    }


    #endregion

    #region Methods

    // Validating Forms
    private void ValidateAllData(Object sender)
    {
        bool errorFlag=false;

        if (!Validate_VehicleNo())
        {
            errorFlag = true;
        }
        if (!Validate_Model())
        {
            errorFlag = true;
        }

        if (!Validate_ManufacturingDate())
        {
            errorFlag = true;
        } 
        if (!Validate_IUNo())
        {
            errorFlag = true;
        }
        if (!Validate_PersonnelName()) // For Future Enhancement
        {
            errorFlag = true;
        }

        // Personnel Remaining..........//

        if (errorFlag)
            throw (new Exception("Invalid Details\nClick on Help for details"));


    }
    public void ValidateSpecificData(Object sender, int ErrorObj)
    {
        bool errorFlag = false;

        if (sender is VehicleMainViewModel)
        {
            VehicleMainViewModel senderObject = (VehicleMainViewModel)sender;

            errorFlag = false;
            switch(ErrorObj)
            {
                case 1:
                    if (!Validate_VehicleNo())
                    {
                        senderObject.VehicleNo_Error = "3 Caps alphabet following 4 numericals only";
                        errorFlag = true;
                    }
                    else
                        senderObject.VehicleNo_Error = "";
                    break;
                case 2:
                    if (!Validate_Model())
                    {
                        senderObject.Model_Error = "Mandatory Field";
                            errorFlag = true;
                    }
                    else
                        senderObject.Model_Error = "";
                    break;
                case 3:
                    if (!Validate_ManufacturingDate())
                    {
                        senderObject.ManufacturingDate_Error = "Can't be blank or future Date";
                        errorFlag = true;
                    }
                    else
                        senderObject.ManufacturingDate_Error = "";
                    break;
                case 4:
                    if (!Validate_IUNo())
                    {
                        senderObject.IUNo_Error = "10 digits numerical only";
                        errorFlag = true;
                    }
                    else
                        senderObject.IUNo_Error = "";
                    break;
                case 5:
                    if (!Validate_PersonnelName())
                    {
                        senderObject.Personnel_Error = "Mandatory Fvnield";
                        errorFlag = true;
                    }
                    else
                        senderObject.Personnel_Error = "";
                    break;
            }

        }
    }
    // To Check Regular Expressions
    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);
    }

    #region Validate Methods

    public bool Validate_VehicleNo()
    {
        if (VehicleNo == null || VehicleNo.Trim().Length==0)
            return false;
        if (matchRE(VehicleNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
            return true;
        else
            return false;
    }
    public bool Validate_Model()
    {
        if (Model == null || Model.Trim().Length==0)
            return false;
        if(Model!=null || Model.Length==0)
            return true;
        else
            return false;
    }
    public bool Validate_ManufacturingDate()
    {
        if (ManufacturingDate == null || ManufacturingDate.ToString().Trim().Length == 0)
            return false;
        if( ManufacturingDate > DateTime.Now )
            return false;
        return true;
    }
    public bool Validate_IUNo()
    {
        if (IUNo == null || IUNo.Trim().Length==0)
            return false;
        if(matchRE(IUNo,"[0-9]{10}"))
            return true;
        else
            return false;
    }
    public bool Validate_PersonnelName()
    {
        if (PersonnelNameSelected == null || PersonnelNameSelected.Trim().Length == 0)
            return false;
        else
            return true;

    }  


    #endregion

    #endregion

    #region Constructors

    public VehicleModel(string VehicleNo, string Model, DateTime? ManufacturingDate, string IUNo, string PersonnelNameSelected)
    {
        this.UniqueNo = Guid.NewGuid();
        this.VehicleNo = VehicleNo;
        this.Model = Model;
        this.ManufacturingDate = ManufacturingDate;
        this.IUNo = IUNo;
        this.PersonnelNameSelected = PersonnelNameSelected;

        ValidateAllData(this);
    }

    public VehicleModel()
    {
        UniqueNo = null;
        VehicleNo = null;
        Model = null;
        ManufacturingDate = null;
        IUNo = null;
        PersonnelNameSelected = null;

    }
    #endregion
}
}

AddVehicle.xaml

<Window x:Class="Seris.Views.AddVehicle"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="AddVehicle" Height="650" Width="750"
    xmlns:l="clr-namespace:Seris.ViewModels">
<Grid>

    <Label Content="Add Vehicle" HorizontalAlignment="Left" Height="27" Margin="261,8,0,0" VerticalAlignment="Top" Width="85" FontWeight="Bold" FontSize="12"/>
    <Label Content="SERIS CAD" HorizontalAlignment="Left" Height="30" Margin="61,5,0,0" VerticalAlignment="Top" Width="84" FontWeight="Bold"/>
    <Menu x:Name="AddNewPersonnel" HorizontalAlignment="Left" Height="32" Margin="10,32,-329,0" VerticalAlignment="Top" Width="611">
        <MenuItem Header="Manage Vehicle &gt;&gt;" Margin="0" />
        <MenuItem Header="Add Vehicle &gt;&gt;" Margin="0" />
    </Menu>
    <GroupBox Header="Vehicle Information" HorizontalAlignment="Left" Height="267" Margin="10,64,0,0" VerticalAlignment="Top" Width="611" FontWeight="Bold" FontSize="12"/>
    <Canvas HorizontalAlignment="Left" Height="352" Margin="18,91,0,0" VerticalAlignment="Top" Width="603">

        <Label Content="Vehical No" HorizontalAlignment="Left" Height="27" Width="104" Margin="10,10,0,232"/>
        <TextBox Name="VehicalNo_Text" Height="27" Width="193" TextWrapping="Wrap" MaxLength="7" Text="{Binding VehicleNo, UpdateSourceTrigger=PropertyChanged}"  HorizontalAlignment="Left" Margin="85,10,0,239" />
        <Label Name="VehicleNoError_Label" Foreground="Red" Content="{Binding VehicleNo_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="10"/>

        <Label Content="Model" HorizontalAlignment="Left" Height="27" Width="104" RenderTransformOrigin="0.49,-2.185" Canvas.Left="10" Canvas.Top="62"/>
        <TextBox Name="Model_Text" Height="27" Width="193" TextWrapping="Wrap" MaxLength="15" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Canvas.Left="85" Canvas.Top="62" />
        <Label x:Name="ModelError_Label" Foreground="Red" Content="{Binding Model_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="62"/>

        <Label Content="Manu. Date" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="112"/>
        <DatePicker x:Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="193" Height="25" Canvas.Left="85" Canvas.Top="114"/>
        <Label Name="ManufacturingDateError_Label" Foreground="Red" Content="{Binding ManufacturingDate_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="112"/>

        <Label Content="IU No" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="157"/>
        <TextBox Height="27" Width="193" Name="IUNO_Text" TextWrapping="Wrap" MaxLength="10" Text="{Binding IUNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Canvas.Left="85" Canvas.Top="157"/>
        <Label Name="IUError_Label" Foreground="Red" Content="{Binding IUNo_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="157"/>

        <Label Content="Personnel" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="198"/>
        <ComboBox x:Name="Personnel_Combo" SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding PersonnelName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="27" Width="193" Canvas.Left="85" Canvas.Top="198"/>
        <Label Name="Personnel_Label" Foreground="Red" Content="{Binding Personnel_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="318" Canvas.Top="198"/>

    </Canvas>

    <Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Width="236" Margin="187,345,0,200"/>

    <Button Name="Help" Visibility="{Binding HelpVisibility, UpdateSourceTrigger=PropertyChanged}" Command="{Binding OpenHelpWindow_Command}" Height="50" Width="50" Margin="562,377,80,143">
        <Button.DataContext>
            <l:VehicleHelpViewModel />
        </Button.DataContext>
        <Image Height="45" Width="45" Source="../Images/help.jpg"/>
    </Button>

    <Button Name="Save_Button" Command="{Binding SaveButton_Command}" CommandParameter="save" Height="28" Width="81" Content="Save" Margin="265,392,346,150"/>

    <TextBlock Name="Preview" Text="{Binding EditText, UpdateSourceTrigger=PropertyChanged}" Margin="13,377,542,168"/>


</Grid>
</Window>

2 个答案:

答案 0 :(得分:1)

您可以通过像这样

初始化来创建ObservableCollection
PersonnelName = new ObservableCollection(PersonnelObject.Select(x => x.Name));  

或者

PersonnelName = new ObservableCollection<string>(PersonnelObject.Select(x => x.Name));

答案 1 :(得分:1)

因为Select方法返回IEnumerable<T>,你可能会这样做

IEnumerable<string> personNames = PersonnelObject.Select(x => x.Name);
PersonnelName = new ObservableCollection<string>();// optional if not initialized
foreach(string pName in personNames )
{
    PersonnelName.Add(pName);
}

因为Select方法返回一个IEnumerable,它不会传播源集合中所做的更改,你也许可以通过绑定自身解决问题

这是组合框的样本

<ComboBox ItemsSource="{Binding PersonnelObject}"
          DisplayMemberPath="Name" />

在上面的示例中,ComboBox在显示PersonnelObject属性时绑定到源集合Name


您可能会将绑定修改为

<ComboBox x:Name="Personnel_Combo"
          SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}"
          ItemsSource="{Binding PersonnelObject}"
          DisplayMemberPath="Name"
          SelectedValuePath="Name"
          HorizontalAlignment="Left"
          Height="27"
          Width="193"
          Canvas.Left="85"
          Canvas.Top="198" />

请注意,我已将ItemsSource更改为绑定到PersonnelObject,并使用SelectedValuePathDisplayMemberPath属性显示并存储正确的值。