2015-05-22 185 views
1

我的目标是创建将文本属性添加到R​​ichTextBox。我创建了附加属性并将绑定设置为ViewModel的属性。不幸的是,在RichTextBox中更改文本不会更新基础属性。WPF将ViewModel属性绑定到附加属性

这里是我的代码:

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.c S:

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中设置一些文本时,底层属性没有更新。

我错过了什么?提前致谢。

+0

抢下窥探,看看发生了什么事情,在用户界面的结合。 – Will

+0

@Will你是什么意思? – Divh

+0

去搜索“snoop”。您可以浏览正在运行的wpf应用程序的可视化树并查看绑定错误。走!跑!这很棒。 – Will

回答

0

也许

Mode=TwoWay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged 

上的绑定失踪?

+0

不幸的是,这是行不通的。已经尝试过。 – Divh

+0

您尚未将富文本框的文本属性绑定到任何内容。 您需要绑定{文本装订,的RelativeSource = {自我的RelativeSource} –

+0

它不起作用,因为RichTextBox中没有对自己的Text属性。我创建了名为Text的Attached属性,然后我想绑定到我的viewmodel的Text属性。正如我在上面我的一个评论中所说的,只有从RichTextBox到Property的绑定不起作用。当我编程设置绑定属性RichTextBox更新就好了。 – Divh

0

代码中没有任何内容显示Attached属性绑定到RichTextBox事件,因此如果RichTextBox中的内容/文本发生更改,它将不会被调用。您需要订阅RichTextBox.TextChangedevent

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类是其中DesiredPropertyProperty设置在
  • OnDesiredPropertyChanged方法将属性值改变时调用对象的实例

在一个侧面说明:

你应该有代码-B在视图后面。没有要求依赖属性或附加属性必须在同一个类内定义。

后面的代码应该只被使用,如果它是一个可重复使用的用户控件,但你的类的命名表明,它不是一个用户控件(即使它派生形式的用户控制),但查看。

视图是应用特定的,不能被该特定的应用程序以外的重复使用,只是为了显示特定内容。如果你创建一个“LoginControl”,那么它可以被重用于其他。另一方面的“LoginView”并不意味着可重用性。