我做了一个简单的测试来尝试找出组合框遇到的问题。我想让用户有机会在触发计算之前取消对控件所做的编辑。
在测试中,文本框给出了我正在寻找的结果。取消时,控件将恢复到原来的状态。当取消组合框中的输入时,组合框看起来就像没有被取消一样。在这两种情况下,模型和视图模型都是正确的。
如何让组合框的行为与文本框相同,以允许控件正确反映视图模型?
模型和视图模型:
Option Explicit On
Option Strict On
Imports System.ComponentModel
Public Class ViewModel
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Overridable Sub OnPropertyChanged(propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Sub New()
Model = New Model
End Sub
Public Property Model As Model
Public Property Text As String
Get
Return Model.Text
End Get
Set(value As String)
If cancel() Then
OnPropertyChanged("Text")
Exit Property
End If
Model.Text = value
OnPropertyChanged("Text")
End Set
End Property
Private Function cancel() As Boolean
If MsgBox("Cancel?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
Return True
Else Return False
End If
End Function
End Class
Public Class Model
Public Sub New()
Text = "Hello, World!"
End Sub
Public Property Text As String
End Class
查看:
<Window x:Class="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:test"
mc:Ignorable="d"
Title="MainWindow" Height="241" Width="416" d:DataContext="{d:DesignInstance Type=local:ViewModel}">
<Grid>
<TextBox HorizontalAlignment="Left" Margin="108,95,0,0" TextWrapping="Wrap" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<ComboBox HorizontalAlignment="Left" Margin="108,144,0,0" VerticalAlignment="Top" Width="120" IsEditable="True" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
窗口代码隐藏:
Class MainWindow
Public Sub New()
InitializeComponent()
DataContext = New ViewModel
End Sub
End Class
因为
ComboBox
包含TextBox
,当用户Cancel()
时,不会影响TextBox.Text
,这就是为什么会出现这个问题。
我们可以添加一个
Button
,并在其Click
事件中获取Text
、Model
的ComboBox
属性以及TextBox
内部的ComboBox
。
我用的是C#,相信你应该能理解。
// in Button click event
// get TextBox inside the ComboBox
var textBox = cb.Template.FindName("PART_EditableTextBox", cb) as TextBox;
MessageBox.Show($"model: {Model.Text}, cb: {cb.Text}, textBox: {textBox.Text}");
我用这个方法解决了这个问题。你可以尝试一下。
<ComboBox x:Name="cb" IsEditable="True" Text="{Binding Path=Text, Delay=5}" />