使用此解决方法:
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 中丢失了 :)