当我遇到一个我似乎无法弄清的MVVM Light中的RaisePropertyChanged问题时,我正在一个项目上。当我尝试对列表进行更改时,列表确实会更新,但是上面选择的索引值也会更新。传递给我选择的索引的值似乎受按下哪个键触发事件的影响(即,如果我按“ BACKSPACE”,则传递给设置器的值是“ -1”,而如果输入字母,传递的值为“ 0”)
我重新创建了一个纯粹演示该问题的项目。以下是MainVeiwModel中发现的主要逻辑部分:
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
_testItems = new List<TestItem>()
{
new TestItem() { Name = "Test1" },
new TestItem() { Name = "Test2" }
};
}
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
RaisePropertyChanged("SelectedIndex");
RaisePropertyChanged("SelectedText");
RaisePropertyChanged("TestList");
}
}
public string SelectedText
{
get
{
return _testItems[_selectedIndex].Name;
}
set
{
_testItems[_selectedIndex].Name = value;
RaisePropertyChanged("TextList");
}
}
public List<string> TextList
{
get
{
_textList = new List<string>();
if (_testItems != null && _testItems.Count > 0)
{
foreach (TestItem item in _testItems)
_textList.Add(item.Name);
}
return _textList;
}
set { _textList = value; }
}
private int _selectedIndex;
private List<string> _textList;
private List<TestItem> _testItems;
}
我的XAML:
<Window x:Class="RaisePropertyBug.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:RaisePropertyBug"
mc:Ignorable="d"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding TextList, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding SelectedIndex, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Text="{Binding SelectedText, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
对于上下文:我有一个ComboBox,其中列出了我所拥有的项目集合中的名称。有一个编辑窗口,用户可以在其中更改这些项目的名称和其他属性。我的目标是在用户编辑值时更新ComboBox列表。在我的实际程序中,您可以使用索引0处的项目执行此操作,但是只要按下一个键并到达RaisePropertyChanged()区域,任何其他索引就会自动更改为0。
答案 0 :(得分:0)
检查下面的代码是否符合您的要求。
使用ImageIcon al = new ImageIcon(getClass().getResource("Walmart.jpeg"));
的{{1}}属性,并将selecteditem绑定到编辑屏幕/文本框。我在这里绑定了SelectedItem
的建议。
查看-
ComboBox
View.cs-
SelectedTestItem.Name
答案 1 :(得分:0)
在此示例中,您甚至不需要INotifyPropertyChanged。我不确定您要实现的目标,但是此代码将实现我从您的帖子中学到的东西。
<Window x:Class="RaisePropertyChangedExample.BindingExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Correct View" Width="150" Height="80">
<StackPanel Orientation="Vertical">
<ComboBox ItemsSource="{Binding Items}"
x:Name="ItemViews"
HorizontalAlignment="Stretch" VerticalAlignment="Center" DisplayMemberPath="Name"/>
<TextBox DataContext="{Binding SelectedItem, ElementName=ItemViews}" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
</StackPanel>
</Window>
和支持代码
using System.Windows;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace RaisePropertyChangedExample
{
public partial class BindingExample : Window
{
public BindingExample()
{
InitializeComponent();
DataContext = new BindingExampleViewModel();
}
}
public class BindingExampleViewModel
{
public ObservableCollection<TestItemViewModel> Items { get; set; }
= new ObservableCollection<TestItemViewModel>(new List<TestItemViewModel>
{
new TestItemViewModel {Name = "Test1"},
new TestItemViewModel {Name = "Test2"}
});
}
public class TestItemViewModel
{
public string Name { get; set; }
}
}
除非所选index
中的Item
有一定的需求,否则没有真正的理由反对将每个项目简单地公开为TestItemViewModel
视图模型并将其他控件直接绑定到所选项目本身。但是,如果将其他控件绑定到TestItemViewModel
的成员上,那么在该视图模型上实现INotifyPropertyChanged仍然不一定。
下面的示例与现有的ViewModel连线时仍将显示正确的信息:
<Window x:Class="RaisePropertyChangedExample.BindingExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Correct View" Width="150" Height="100">
<StackPanel Orientation="Vertical">
<ComboBox ItemsSource="{Binding Items}"
x:Name="Combo"
HorizontalAlignment="Stretch" VerticalAlignment="Center" DisplayMemberPath="Name"/>
<Grid DataContext="{Binding SelectedItem, ElementName=Combo}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
<Label Grid.Row="1" HorizontalAlignment="Stretch" Height="20" Content="{Binding Name}" />
</Grid>
</StackPanel>
</Window>
通常
每次击键后进行更新都会降低性能,并且会剥夺用户通常在提交新值之前退格并修复键入错误的机会。 see MS reference
但是,仅当更新源进行其他处理时,这才是问题。如果您担心所涉及的处理量,可以通过简单地省略“ UpdateSourceTrigger”声明来切换到默认行为LostFocus
。