2011-02-13 22 views
2

次の関数listView_SelectionChangedをコードビハインドから離れて、直接ViewModel(またはXAMLとして直接)内で処理しようとしています。そして、私は誰かがこれを実装する方法についてもっと良いアイデアを持っていることを期待していました。ListBoxを使用してMVVMを使用してTextBoxを移動する

TextBoxには、セクションが含まれています。 [Secion1]とナビゲートするのに役立ちます私はの側面にすべてのセクションのリストを含むListBoxを持っています。セクションの1つをクリックすると、自動的にテキストのその部分にジャンプします。

コードは、現在、このようなものになります。コードビハインド

XAML

ListBox ItemsSource="{Binding Path=Sections}" Name="listBox" 
         SelectionMode="Single" Width="170" 
         DisplayMemberPath="Section" 
         SelectionChanged="listView_SelectionChanged"/> 

<TextBox Name="TextBox1" Text="{Binding Path=Source}"/> 

モデル

public class SourceData 
{ 
    public SourceData() 
    { 
     Sections = new List<SectionData>(); 
    } 

    public String Source { get; set; } 

    public List<SectionData> Sections { get; set; } 
} 

public class SectionData 
{ 
    public int Line { get; set; }  // Line of the Section 
    public String Section { get; set; } // Section name (e.g. [Section1] 
} 

private void listView_SelectionChanged(object sender, 
           System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    var test = (SectionData)listBox.SelectedItem; // Get Information on the Section 

    if (test.Line > 0 && test.Line <= TextBox1.LineCount) // Validate 
    { 
     TextBox1.ScrollToLine(test.Line - 1); // Scroll to Line 
    } 
} 

答えて

3

このような状況では、通常、添付されたビヘイビアを作成します(この場合は、テキストボックスのスクロールされた行を同期させる動作になります)、ViewModel(SourceData)プロパティ。あなたがあなたのケースで行う必要があります

手順(私はあなたが添付プロパティを作成する方法を知っていると仮定):

1)テキストボックスのために付属の行動ScrolledLineを作成します。少なくともone-wayバインディングをサポートする必要があります。添付のプロパティコールバックでは、(動作がアタッチされている)textBoxをlineにスクロールします。このような動作を実装する方法の簡単な例を以下に示します。

2)あなたのSourceDataは、少なくとも2つのプロパティ:SelectedSectionScrolledLineで拡張する必要があります。 ScrolledLineは、PropertyChangedを上げる必要があります。 SelectedSectionセッターはScrolledLineを変更する必要があります。

private SectionData _selectedSection; 
public SectionData SelectedSection 
{ 
    get { return _selectedSection; } 
    set 
    { 
     _selectedSection = value; 
     if (_selectedSection != null) SelectedLine = _selectedSection.Line; 
    } 
} 

3)これら2つの新しいプロパティへのあなたの視野バインド:以下

bは#1

<ListBox ItemsSource="{Binding Path=Sections}" SelectionMode="Single" Width="170" DisplayMemberPath="Section" SelectedItem="{Binding SelectedSection, Mode=TwoWay}" /> 

<TextBox Text="{Binding Path=Source}" b:Behaviors.ScrolledLine="{Binding ScrolledLine}" /> 

4)から、あなたの添付行動するためのXML名前空間ですビューからlistView_SelectionChangedイベントハンドラを削除します。今からあなたのビューにはInitializeComponent以外のコードはありません。

public class b:Behaviors 
{ 
    #region Attached DP registration 

    public static int GetScrolledLine(TextBox obj) 
    { 
     return (int)obj.GetValue(ScrolledLineProperty); 
    } 

    public static void SetScrolledLine(TextBox obj, int value) 
    { 
     obj.SetValue(ScrolledLineProperty, value); 
    } 

    #endregion 

    public static readonly DependencyProperty ScrolledLineProperty= 
    DependencyProperty.RegisterAttached("ScrolledLine", typeof(int), typeof(Behaviors), new PropertyMetadata(ScrolledLine_Callback)); 

    // This callback will be invoked when 'ScrolledLine' property will be changed. Here you should scroll a textbox 
    private static void ScrolledLine_Callback(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     var textbox = (TextBox) source; 

     int newLineValue = (int)e.NewValue; 

     if (newLineValue > 0 && newLineValue <= textBox.LineCount) // Validate 
      textbox.ScrollToLine(newLineValue - 1); // Scroll to Line 
    } 
} 
+0

どうもありがとうSnowbear:

P.S:ここでは、あなたの添付の行動がどのように見えるべきかのサンプルです。前にACB以外の付随行動を使ったことはありませんでしたが、指導を受けて私はそれを手に入れて働きました。 – eandersson

+2

@Fuji、添付されたビヘイビアは、MVVMコンセプトのビューとviewModelsをまとめるために非常に重要です。 ABが多くを助けるかもしれないこのような多くのケースがあります。 – Snowbear

+0

スノーボード、もう一度感謝します。私のアプリケーションが拡大するにつれてこれが役立つより多くの状況があると確信しています。あなたのサンプルコードに新しいPropertyMetadataの中に新しいPropertyChangedCallbackがありませんでした。 @Fuji。 – eandersson

関連する問題