WPF将ViewModel属性绑定到附加属性
本文关键字:属性 绑定 ViewModel WPF | 更新日期: 2023-09-27 17:50:24
我的目标是创建添加文本属性的RichTextBox。我创建了附加属性并设置绑定到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()
{
}
}
}
我知道Callback抛出和异常,但我这里的目标只是在调试器下看到这个回调被调用。然后我添加正确的实现。
编辑:我想我的问题漏掉了重要的一点。当我从代码中更新TextToSearchArg属性时,一切工作正常。唯一的问题是,当我设置一些文本在RichTextBox底层属性不更新。
我错过了什么?
代码中没有任何内容显示Attached属性绑定到RichTextBox
事件,因此如果RichTextBox
中的内容/文本发生变化,它将永远不会被调用。
你需要订阅RichTextBox.TextChanged
事件。
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
is the name of your property (i.e.
TextProperty ' -
dependencyObject
是在 上设置 -
OnDesiredPropertyChanged
方法,当属性值改变时调用
DesiredPropertyProperty
的对象实例。边注:
视图中应该有Code-Behind。不要求依赖属性或附加属性必须在与它们对应的同一个类中定义。
后面的代码应该只使用,如果它是一个可重用的用户控件,但你的类的命名表明它不是一个用户控件(即使它派生自用户控件),而是一个视图。
视图是特定于应用程序的,不能在特定应用程序之外重用,只能显示特定的内容。如果你做了一个"LoginControl",那么它就可以在其他地方重复使用。另一边的"LoginView"并不意味着可重用性。
可能
Mode=TwoWay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged
上的绑定缺失?