Silverlight MVVM灯光太快:)
我有一个带有Silverlight MVVM灯光太快:),silverlight,windows-phone-7,mvvm,command,mvvm-light,Silverlight,Windows Phone 7,Mvvm,Command,Mvvm Light,我有一个带有文本框的简单WM7页面。此外,我将事件分配给命令(一个RelayCommand)给这个文本框,对文本更改事件作出反应。为了测试pourposes,我在页面的代码隐藏中添加了额外的方法TextBox\u TextChanged。命令和TextBox\u TextChanged打印包含TextBox内容的消息框 文本框的初始值为“ABC”。然后我按D键,然后: TextBox\u TextChanged打印ABCD 该命令打印ABC。D不见了 为什么命令这么快 命令声明: public
文本框的简单WM7页面。此外,我将事件分配给命令
(一个RelayCommand
)给这个文本框
,对文本更改
事件作出反应。为了测试pourposes,我在页面的代码隐藏中添加了额外的方法TextBox\u TextChanged
。命令和TextBox\u TextChanged
打印包含TextBox内容的消息框
文本框的初始值为“ABC”
。然后我按D键,然后:
TextBox\u TextChanged
打印ABCD
该命令打印ABC
。D不见了
为什么命令这么快
命令声明:
public RelayCommand<string> TextChanged {get; private set;}
public RelayCommand<string> TextChanged {get; private set;}
public RelayCommand TextChanged{get;private set;}
命令初始化:
TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
TextChanged=newrelaycommand(=>MessageBox.Show));
命令绑定:
<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
我无法重现这种行为。我尝试过使用EventToCommand和行为(它只是侦听TextChanged事件)
在没有看到代码的情况下,我怀疑这可能与如何获取搜索框的文本或其他地方的逻辑错误有关
这是我如何使用EventToCommand的一个片段:
<TextBox Name="SearchTextBox">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding TestTextChangedCommand,Mode=OneWay}" CommandParameter="{Binding Path=Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
<i:Interaction.Triggers>
</TextBox>
在viewmodel中
m_TestTextChangedCommand = new RelayCommand<string>(val => System.Diagnostics.Debug.WriteLine(val));
m_TestTextChangedCommand=newrelaycommand(val=>System.Diagnostics.Debug.WriteLine(val));
如您所见,我使用commandparameter将文本框的值传递给viewmodel。这样,viewmodel就不必知道文本框来获取文本值
这种方法的另一种选择是使用行为和双向绑定来更新属性:
<TextBox Name="SearchTextBox" Text="{Binding TextInViewModel, Mode=TwoWay}" >
<i:Interaction.Behaviors>
<sc:UpdateOnTextChangedBehavior/>
</i:Interaction.Behaviors>
</TextBox>
UpdateOnTextChangedBehavior类:
public class UpdateOnTextChangedBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.TextChanged +=
new TextChangedEventHandler(AssociatedObject_TextChanged);
}
void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(((TextBox)sender).Text);
BindingExpression binding =
this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.TextChanged -=
new TextChangedEventHandler(AssociatedObject_TextChanged);
}
}
公共类UpdateOnTextChangedBehavior:行为
{
受保护的覆盖无效附加()
{
base.onatached();
this.AssociatedObject.TextChanged+=
新的TextChangedEventHandler(关联对象\u TextChanged);
}
无效关联对象\u TextChanged(对象发送者,textchangedventargs e)
{
System.Diagnostics.Debug.WriteLine(((文本框)sender.Text);
BindingExpression绑定=
this.AssociatedObject.GetBindingExpression(TextBox.TextProperty);
if(绑定!=null)
{
binding.UpdateSource();
}
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
this.AssociatedObject.TextChanged-=
新的TextChangedEventHandler(关联对象\u TextChanged);
}
}
上面所做的是模仿桌面WPF与UpdateSourceTrigger=PropertyChanged
绑定的行为,这在Silverlight中是缺失的。那么,每当您在文本框中键入TextInViewModel
属性时,将会发生什么情况呢。此属性不必是DependencyProperty
,它可以是普通的CLR属性。我使用的一些代码(类似于您的命令示例):
命令声明:
public RelayCommand<string> TextChanged {get; private set;}
public RelayCommand<string> TextChanged {get; private set;}
public RelayCommand TextChanged{get;private set;}
命令初始化:
TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
TextChanged=newrelaycommand(=>MessageBox.Show));
命令绑定:
<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
出于某些原因,messagebox显示一个带有一个字符延迟的字符串。这通过RelayCommand的参数与TextBox一起工作。IOW-RelayCommand
public RelayCommand SearchedTextChanged{get;set;}
SearchedTextChanged=新的RelayCommand(OnSearchedTextChanged);
SearchedTextChanged上的私有无效(文本框val)
{
如果(val!=null)
{
系统.诊断.调试.写入线(val.Text);
}
}
我也遇到了类似的问题,发现在文本框失去焦点之前,数据绑定操作并不总是启动。然而,命令将立即开火
如果要确保在使用该值之前已进行数据绑定,可以调用控件上的BindingExpression.UpdateSource()
方法。试着这样做:
var bindTarget=SearchTextBox.GetBindingExpression(TextBox.TextProperty);
bindTarget.UpdateSource();
为了避免在ViewModel中直接引用文本框(MVVM应该这样做),可以使用FocusManager.GetFocusedElement()
。这在处理应用程序栏按钮时特别有用,因为它们在使用时似乎没有焦点。您能发布代码吗?如果看不到它们是如何连接在一起的,就很难确定。WM7是指Windows Phone 7吗?为galasoft mvvm light support添加mvvm light标记:)@Sky-是的,他想知道为什么两个代表响应同一事件会产生不同的结果。当附加了事件处理程序时,该命令似乎在绑定发生之前运行。与仅供参考一样,TextBox.TextChanged事件在A)TextBox失去焦点或B)文本通过文本属性或自动更正事件更改之前不会触发。可能是TextChanged事件有两个侦听器会产生副作用,导致它们报告不同的事件。欢迎使用stackOverflow!请注意,您不应该在这里发布回复作为答案,或者使用评论或编辑原始帖子,答案没有任何顺序。