问题描述
我有一个简化的案例:
- MainWindow显示一个TextBox和一个UserControl。
- UserControl具有一个依赖项属性,用于接收TextBox文本(在XAML窗口中绑定)
- 接收到的文本绑定到UserControl代码后台的view-model属性。
- 视图模型将输入文本转换为驼峰式大小写。
- 使用UserControl中的TextBlock显示驼峰案例文本。
我可以看到用户控件收到了正确的TextBox值,但是该值没有到达视图模型,我不明白为什么。
MainWindow
Window x:Class="WpfApp5.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:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Label Content="Original:"/>
<TextBox x:Name="tb"/>
<local:CamelStringBox OriginalText="{Binding ElementName=tb,Path=Text,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Window>
隐藏代码:
using System.Windows;
namespace WpfApp5 {
public partial class MainWindow : Window {
public MainWindow () {
InitializeComponent ();
}
}
}
UserControl CamelStringBox
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
x:Class="WpfApp5.CamelStringBox"
xmlns:local="clr-namespace:WpfApp5">
<UserControl.DataContext>
<local:CamelStringBoxViewModel x:Name="vm"/>
</UserControl.DataContext>
<StackPanel>
<Label Content="Camelized String:"/>
<TextBlock Text="{Binding ElementName=vm,Path=CamelizedText}"/>
</StackPanel>
</UserControl>
隐藏代码:
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfApp5 {
public partial class CamelStringBox : UserControl {
public string OriginalText {
get { return (string) GetValue (OriginalTextProperty); }
set { SetValue (OriginalTextProperty,value); }
}
public static readonly DependencyProperty OriginalTextProperty =
DependencyProperty.Register (
"OriginalText",typeof (string),typeof (CamelStringBox),new PropertyMetadata (
(d,e) => Debug.WriteLine ($"Value received by UserControl: {e.NewValue}")));
public CamelStringBox () {
InitializeComponent ();
// Bind user control OriginalText to view-model Text (doesn't work)
if (DataContext == null) Debug.WriteLine ($"{GetType ()}: DataContext is null");
else SetBinding (OriginalTextProperty,new Binding {
Path = new PropertyPath (nameof (CamelStringBoxViewModel.Text)),Mode = BindingMode.TwoWay
});
}
}
public class CamelStringBoxViewModel : ChangeNotifier {
private string text;
private string camelizedText;
public string Text {
get => text;
set {
text = value;
RaisePropertyChanged ();
}
}
public string CamelizedText {
get => camelizedText;
private set {
camelizedText = value;
RaisePropertyChanged ();
}
}
// Never triggered
private void OnPropertyChanged (object sender,PropertyChangedEventArgs e) {
if (e.PropertyName == nameof (Text)) CamelizedText = Camelize (Text);
}
private string Camelize (string text) {
if (text == null || text.Length == 0) return null;
string[] s = text.ToLower ().Split (' ');
for (int i = 0; i < s.Length; i++) s[i] = char.ToUpper (s[i][0]) + s[i].Substring (1);
return string.Join (" ",s);
}
}
public class ChangeNotifier : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged ([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke (this,new PropertyChangedEventArgs (propertyName));
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)