2015-05-22 151 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」並不意味着可重用性。