【发布时间】:2011-07-17 08:23:12
【问题描述】:
场景:在 Silverlight 4 MVVM 项目中,我们有一个包含项目的 ListBox 控件,所选项目被双向绑定到 ViewModel 中的适当属性。另一个控件(例如原因,我已将其简化为单个 TextBox)是绑定到所选项目内容的数据。该值应在离开/失去焦点时更新。
问题:当TextBox 中的值发生更改并且我们通过按Tab 键离开TextBox 时,一切都按预期工作- 值已更新。但是,如果用户单击 ListBox 中的其他项目,则 SelectedItem 设置器会在TextBox 设置器的内容被触发之前触发,从而没有机会处理用户输入。
您可以在调试器中看到,当向属性设置器添加断点时,会首先应用新的 ListView 选择,然后再处理 TextBox 更新。
期望行为:我们需要知道在用户选择另一个项目之前,当前选择的项目已被修改。不希望有一个自定义更新触发器,它会在每次按键时通知(我们知道这是可能的)。
你能帮忙吗?
代码(一个非常简单的例子):
视图模型
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class ItemViewModel : ViewModelBase
{
private string _content;
public ItemViewModel(string initContent)
{
_content = initContent;
}
public string Content
{
get
{
return _content;
}
set
{
if (_content != value)
{
_content = value;
OnPropertyChanged("Content");
}
}
}
}
public class MainViewModel : ViewModelBase
{
private ObservableCollection<ItemViewModel> _items =
new ObservableCollection<ItemViewModel>();
private ItemViewModel _selectedViewModel;
public ObservableCollection<ItemViewModel> Items
{
get
{
return _items;
}
}
public ItemViewModel SelectedItem
{
get
{
return _selectedViewModel;
}
set
{
if (_selectedViewModel != value)
{
_selectedViewModel = value;
OnPropertyChanged("SelectedItem");
}
}
}
}
XAML
<Grid x:Name="LayoutRoot" Background="White">
<ListBox Height="100"
HorizontalAlignment="Left"
Margin="12,12,0,0"
VerticalAlignment="Top"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
DisplayMemberPath="Content"
Width="220" />
<TextBox Height="23"
HorizontalAlignment="Left"
Margin="12,118,0,0"
Text="{Binding SelectedItem.Content, Mode=TwoWay}"
VerticalAlignment="Top"
Width="220" />
</Grid>
XAML 代码隐藏
public MvvmTestView()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MvvmTestView_Loaded);
}
void MvvmTestView_Loaded(object sender, RoutedEventArgs e)
{
MainViewModel viewModel = new MainViewModel();
viewModel.Items.Add(new ItemViewModel("Hello StackOverflow"));
viewModel.Items.Add(new ItemViewModel("Thanks to Community"));
DataContext = viewModel;
}
更新 1 我提供a self designed solution 供您查看,这可能是被接受的,我仍然想鼓励您制作 cmets 并给出您的提示。谢谢。
【问题讨论】:
标签: silverlight data-binding silverlight-4.0 mvvm