我的目标是创建向 RichTextBox 添加 Text 属性。我创建了附加属性并将绑定(bind)设置为 ViewModel 的属性。遗憾的是,更改 RichTextBox 中的文本不会更新基础属性。
这是我的代码:
View.cs:
public partial class KnuthMorrisPrattView : UserControl
{
public KnuthMorrisPrattView()
{
InitializeComponent();
}
public static string GetText(DependencyObject obj)
{
return (string)obj.GetValue(TextProperty);
}
public static void SetText(DependencyObject obj, string value)
{
obj.SetValue(TextProperty, value);
}
public static readonly DependencyProperty TextProperty = DependencyProperty.RegisterAttached
(
"Text",
typeof(string),
typeof(KnuthMorrisPrattView),
new FrameworkPropertyMetadata()
{
BindsTwoWayByDefault = true,
PropertyChangedCallback = PropertyChangedCallback,
CoerceValueCallback = CoerceValueCallback,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.LostFocus
}
);
private static object CoerceValueCallback(DependencyObject dependencyObject, object baseValue)
{
throw new NotImplementedException();
}
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
throw new NotImplementedException();
}
}
View.xaml:
<UserControl x:Class="Launcher.Views.KnuthMorrisPrattView"
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"
xmlns:views="clr-namespace:Launcher.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500"
DataContext="{Binding KnuthMorrisPrattViewModel, Source={StaticResource MainViewModel}}">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="7*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
<Label Content="Text" DockPanel.Dock="Top"></Label>
<RichTextBox x:Name="TextBox" views:KnuthMorrisPrattView.Text="{Binding TextToSearchArg}"/>
</DockPanel>
<DockPanel Grid.Row="1">
<Label Content="Pattern" DockPanel.Dock="Top"></Label>
<TextBox Text="{Binding PatternArg}"/>
</DockPanel>
</Grid>
ViewModel.cs:
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using GalaSoft.MvvmLight.CommandWpf;
using Launcher.Runners.KnuthMorrisPratt;
namespace Launcher.ViewModels
{
public class KnuthMorrisPrattViewModel : ViewModelBase
{
private string _textToSearchArg;
private string _patternArg;
public string TextToSearchArg
{
get { return _textToSearchArg; }
set
{
_textToSearchArg = value;
RaisePropertyChanged();
}
}
public string PatternArg
{
get { return _patternArg; }
set
{
_patternArg = value;
RaisePropertyChanged();
}
}
public KnuthMorrisPrattViewModel()
{
}
}
}
我知道回调会抛出异常,但我的目标是在调试器下看到调用了此回调。然后我添加正确的实现。
编辑: 我想我错过了关于我的问题的重要说明。当我从代码更新 TextToSearchArg 属性时,一切正常。唯一的问题是,当我在 RichTextBox 中设置一些文本时,底层属性没有更新。
我错过了什么?非常感谢。
最佳答案
您的代码中没有任何内容表明 Attached 属性绑定(bind)到 RichTextBox
事件,因此如果 RichTextBox
中的内容/文本发生变化,它永远不会被调用。
您需要订阅 RichTextBox.TextChanged
event .
public partial class KnuthMorrisPrattView : UserControl
{
public KnuthMorrisPrattView()
{
InitializeComponent();
this.TextBox.TextChanged += OnTextChanged;
}
...
public void OnTextChanged(object sender, TextChangedEventArgs e)
{
// Get the text from the event and set your Text Property
string text = ...;
SetText(this, text);
}
}
编辑:
如果你想监听另一个控件的依赖/附加属性的变化,使用
DependencyPropertyDescriptor.FromProperty(ControlClassName.DesiredPropertyProperty, typeof(ControlClassName)).AddValueChanged(dependencyObject, OnDesiredPropertyChanged);
哪里...
ControlClassName
是包含依赖属性的类(即您的情况下的RichTextBox
或定义依赖/附加属性的类- 'DesiredPropertyProperty
是您的属性的名称(即
TextProperty` dependencyObject
是设置了DesiredPropertyProperty
的对象实例OnDesiredPropertyChanged
属性值改变时调用的方法
旁注:
您应该在 View 中有代码隐藏。没有要求必须在同一个类中定义依赖属性或附加属性。
仅当它是可重用的用户控件时才应使用代码隐藏,但您的类的命名表明它不是用户控件(即使它派生自用户控件)而是 View 。
View 是特定于应用程序的,不能在该特定应用程序之外重复使用,只能显示特定内容。如果你制作一个“LoginControl”,那么它可以在其他地方重复使用。另一边的“LoginView”并不意味着可重用性。
关于c# - WPF 将 ViewModel 属性绑定(bind)到附加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30404060/