使用此解决方法:
public class ExtendedTextBox : TextBox
{
public static readonly DependencyProperty CustomActionProperty =
DependencyProperty.Register(
"CustomAction",
typeof(Action<string>),
typeof(ExtendedTextBox),
new PropertyMetadata(null, OnPropertyChanged));
public Action<string> CustomAction
{
get
{
return (Action<string>)GetValue(CustomActionProperty);
}
set
{
SetValue(CustomActionProperty, value);
}
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(e.NewValue != null)
(d as ExtendedTextBox).TextChanged += ExtendedTextBox_TextChanged;
else
(d as ExtendedTextBox).TextChanged -= ExtendedTextBox_TextChanged;
}
async static void ExtendedTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
await CoreWindow.GetForCurrentThread().Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => (sender as ExtendedTextBox).CustomAction((sender as ExtendedTextBox).Text));
}
}
在你的模型:
public Action<string> UpdateBindedViewModelProperty
{
get { return new Action<string>((value) => NewLabelName = value); }
}
和看法:
<plmrfc:extendedtextbox customaction="{Binding UpdateBindedViewModelProperty, Mode=OneTime}" text="{Binding Path=NewLabelName, Mode=TwoWay}" width="200" x:name="Label_TextBox"></plmrfc:extendedtextbox>
也有另一种方式,不涉及子类的TextBox。也许你喜欢这一点:
using System.Reflection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace Flexman
{
public class TextBoxUpdateSourceBehaviour
{
private static PropertyInfo _boundProperty;
public static readonly DependencyProperty BindingSourceProperty =
DependencyProperty.RegisterAttached(
"BindingSource",
typeof(string),
typeof(TextBoxUpdateSourceBehaviour),
new PropertyMetadata(default(string), OnBindingChanged));
public static void SetBindingSource(TextBox element, string value)
{
element.SetValue(BindingSourceProperty, value);
}
public static string GetBindingSource(TextBox element)
{
return (string)element.GetValue(BindingSourceProperty);
}
private static void OnBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var txt = d as TextBox;
if (txt == null)
return;
txt.Loaded += OnLoaded;
txt.TextChanged += OnTextChanged;
}
static void OnLoaded(object sender, RoutedEventArgs e)
{
var txt = sender as TextBox;
if (txt == null)
return;
// Reflect the datacontext of the textbox to find the field to bind to.
var dataContextType = txt.DataContext.GetType();
_boundProperty = dataContextType.GetRuntimeProperty(GetBindingSource(txt));
// If you want the behaviour to handle your binding as well, uncomment the following.
//var binding = new Binding();
//binding.Mode = BindingMode.TwoWay;
//binding.Path = new PropertyPath(GetBindingSource(txt));
//binding.Source = txt.DataContext;
//BindingOperations.SetBinding(txt, TextBox.TextProperty, binding);
}
static void OnTextChanged(object sender, TextChangedEventArgs e)
{
var txt = sender as TextBox;
if (txt == null)
return;
if (_boundProperty.GetValue(txt.DataContext).Equals(txt.Text)) return;
_boundProperty.SetValue(txt.DataContext, txt.Text);
}
}
}
,并查看
<TextBox Text="{Binding Username}" Flexman:TextBoxUpdateSourceBehaviour.BindingSource="Username" />
这是我所知道的最漂亮的解决方案。其他人将是“非通用”黑客。 祝你好运。我不同意,这是从Silverlight的/ WPF重大降级,但嘿,有在WinRT中多了很多可怕的事情是缺少在WPF :)
WinRT/XAML中没有UpdateSourceTrigger或UpdateTarget()。 – 2013-04-05 14:00:55
对不起,我们仍然在办公室使用Win7&VS2010。如果他们之一,我会成为一名富有的工程师,我会买一台PC。然后,我会学到很多东西,并提供更好的答案:) – 2013-04-05 20:20:24