[Combobox'selecteditem在xaml中设置,但绑定属性为null

问题描述 投票:0回答:1

我想用C#进行培训,我创建了一个WPF项目,在其中显示一些人(每个人都有一个名字和一件作品),并通过选择一个字段(“名字”或“作品”)和一个搜索字符串,我会把所有的人都过滤掉。例如,字段是“名称”,字符串是“ tin”,唯一的名字包含“ tin”的人是“ tintin”。我编写了所有程序,但搜索引擎(参数化类的目的是过滤人员)出现空引用错误。

这里是人员类别:

namespace VueEnPremier.Model
{
    public class Person : ViewModelBase
    {
        public string Name { get; set; }

        public string Work { get; set; }

    }
}

这是我的观点:

<Window
        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:VueEnPremier"
        xmlns:vm="clr-namespace:VueEnPremier.ViewModel"
        xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="VueEnPremier.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <!--<vm:VMSearchName x:Key="ByName" />
        <vm:VMSearchWork x:Key="ByWork"/>-->
        <vm:VMSearch x:Key="ByName" NameOfTypeToSearch="Name"/>
        <vm:VMSearch x:Key="ByWork" NameOfTypeToSearch="Work"/>

    </Window.Resources>
    <Grid DataContext="{Binding Source={StaticResource Locator}}">
        <StackPanel>
            <StackPanel x:Name="liste">
                <ComboBox x:Name="comboBox" Width="150" HorizontalAlignment="Left" Margin="10,10,0,10" 
                          SelectedItem="{Binding Main.SearchEngine, Mode=OneWayToSource}">
                    <ComboBoxItem Content="{StaticResource ByName}" HorizontalAlignment="Center" IsSelected="True"/>
                    <ComboBoxItem Content="{StaticResource ByWork}" HorizontalAlignment="Center"/>

                </ComboBox>
                <TextBox Text="{Binding Main.ToFind, Mode=OneWayToSource}"></TextBox>
                <ItemsControl 
                    ItemsSource="{Binding ElementName=comboBox,Path=SelectedItem.(vm:VMSearch.PersonsFiltered)}"/>
            </StackPanel>

        </StackPanel>
    </Grid>

</Window>

这是我的搜索引擎:

namespace VueEnPremier.ViewModel
{
    public class VMSearch : ViewModelBase
    {
        public string ToFind { get; set; }

        public string NameOfTypeToSearch { get; set; }


        public VMSearch(string nameOfTypeToSearch)
        {
            NameOfTypeToSearch = nameOfTypeToSearch;
        }

        public VMSearch() { }

        protected List<Person> Persons { set; get; }


        public void UpdatesDatas(List<Person> persons, string toFind)
        {
            Persons = persons;
            ToFind = toFind;

            RaisePropertyChanged(() => this.PersonsFiltered);

        }

        public override string ToString() => NameOfTypeToSearch;

        public List<Person> PersonsFiltered
        {
            get
            {
                return Persons?.Where(c => (c.GetType().GetProperty(NameOfTypeToSearch).GetValue(c,null) as string).Contains(ToFind)).ToList();
            }
        }

    }
}

PersonsFiltered的getter有点棘手,它从此属性的字符串名称中获取属性的值(“ Name”-> c.Name已获得)。关键是,在XAML中,组合框直接包含2个搜索引擎,并且selectedItem属性应该绑定(一种获取源的方式)到viewmodel的SearchEngine属性:所有逻辑都位于绑定中。

最后是我的视图模型:

using System.Collections.Generic;
using System.Windows.Documents;
using System.Windows.Media.Animation;
using GalaSoft.MvvmLight;
using VueEnPremier.Model;

namespace VueEnPremier.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {

        public List<Person> AllNames { get; set; }

        #region ToFind

        private string _toFind = string.Empty;


        public string ToFind
        {
            get => _toFind;
            set
            {
                _toFind = value;
                RaisePropertyChanged(()=>this.ToFind);
                SearchEngine.UpdatesDatas(AllNames,value);
            }
        }



        #endregion


        #region SearchEngine

        private VMSearch _searchEngine;


        public VMSearch SearchEngine
        {
            get { return _searchEngine; }
            set
            {
                if (value != _searchEngine)
                    _searchEngine = value;
                RaisePropertyChanged("SearchEngine");
            }
        }
        #endregion


        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real"
            ////}

            Fill();

        }

        private void Fill()
        {
            AllNames = new List<Person>();
            AllNames.Add(new Person() {Name = "sanzot", Work = "boucher"});
            AllNames.Add(new Person() {Name = "buck dany", Work = "pilote"});
            AllNames.Add(new Person() {Name = "lefuneste", Work = "cuistre"});
            AllNames.Add(new Person() {Name = "tintin", Work = "reporter"});
            AllNames.Add(new Person() {Name = "blake", Work = "pilote"});

        }
    }
}

我使用MVVM灯。我得到的错误是,在启动时:

System.NullReferenceException HResult = 0x80004003消息= La对象的实例的正确性。来源= VueEnPremier采购程序的树莓派:àVueEnPremier.ViewModel.MainViewModel.set_ToFind(String value)dansC:\ Users \ osain \ source \ repos \ MVVMBook \ VueEnPremier \ ViewModel \ MainViewModel.cs:ligne 38

它说的是'searchEngine.updateDatas(AllNames,value);' searchEngine变量为null。

谢谢。

c# wpf xaml data-binding
1个回答
0
投票

它可能需要UpdateSourceTrigger=PropertyChange

<ComboBox x:Name="comboBox" Width="150" HorizontalAlignment="Left" Margin="10,10,0,10" 
     SelectedItem="{Binding Main.SearchEngine, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChange}">
© www.soinside.com 2019 - 2024. All rights reserved.