Я пытаюсь связать текстовое поле с открытым строковым полем, чтобы отфильтровать список элементов в списке wpf. Я продолжаю получать эту ошибку. Это довольно простая настройка. Код ниже. Я чувствую, что сам код довольно прост, и я не знаю, где проблема. Помощь приветствуется!Связывание с текстовым полем, вызывающим ошибку исключения связывания
По какой-то причине мой список всегда пуст, и он должен сначала отображать имена всех государств, а затем, если в поле «Поиск» содержится текст, он фильтрует список.
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=SearchText; DataItem='MainWindowViewModel' (HashCode=37975124); target element is 'TextBox' (Name='SearchBox'); target property is 'Text' (type 'String') NullReferenceException:'System.NullReferenceException: Object reference not set to an instance of an object.
VNode.cs
namespace WpfApplication1
{
public class VNode
{
public string Name { get; set; }
}
}
ObservableObject.cs
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApplication1
{
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
public class MainWindowViewModel : ObservableObject
{
private ObservableCollection<VNode> _vnodes;
public ObservableCollection<VNode> VNodes
{
get { return _vnodes; }
set
{
_vnodes = value;
NotifyPropertyChanged("VNodes");
}
}
private ObservableCollection<VNode> _vnodesfiltered;
public ObservableCollection<VNode> VNodesFiltered
{
get { return _vnodesfiltered; }
set
{
_vnodesfiltered = value;
NotifyPropertyChanged("VNodesFiltered");
}
}
public MainWindowViewModel()
{
VNodes = new ObservableCollection<VNode>();
// data testing
List<string> names = new List<string>() { "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "DistrictofColumbia", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "NewHampshire", "NewJersey", "NewMexico", "NewYork", "NorthCarolina", "NorthDakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "RhodeIsland", "SouthCarolina", "SouthDakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "WestVirginia", "Wisconsin", "Wyoming" };
foreach (string name in names)
{
var node = new VNode();
node.Name = name;
VNodes.Add(node);
}
}
private string _searchText = "";
public string SearchText
{
get { return _searchText; }
set
{
if (value != _searchText)
{
_searchText = value;
VNodesFiltered.Clear();
if (string.IsNullOrWhiteSpace(SearchText))
{
foreach (var node in VNodes)
{
VNodesFiltered.Add(node);
}
}
else
{
foreach (var node in VNodes)
{
if (node.Name.Contains(SearchText))
{
VNodesFiltered.Add(node);
}
}
}
}
}
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="200"
WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<ListBox>
<ListBox.ContextMenu>
<ContextMenu FocusManager.FocusedElement="{Binding ElementName=SearchBox}">
<ContextMenu.Template>
<ControlTemplate>
<Border BorderThickness="2" BorderBrush="sc#1,.1,.1,.1" CornerRadius="4"
Background="sc#1,.05,.05,.05">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Margin="4" MinWidth="150" Name="SearchBox" VerticalAlignment="Center"
Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
<ListBox Grid.Row="1" MinWidth="150" MaxHeight="300" ItemsSource="{Binding VNodes}">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}" FontWeight="Regular" FontSize="12" />
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</Grid>
</Window>
'VNodesFiltered', вероятно,« null ». –
1) VNodesFiltered - null. 2) Вы не реализовали INotifyPropertyChanged в классе vNode. 3) Вместо очистки VNodesFiltered вы можете изменить его на CollectionViewSource и применить фильтр, хотя и предикат, так что при изменении на SearchText вам потребуется только обновить. – user1672994