2011-02-13 3 views
2

listView_SelectionChanged을 코드 숨김에서 멀리 이동하고 내 ViewModel (또는 직접 XAML) 내에서 직접 처리하려고합니다. 그리고 저는 누군가가 이것을 구현하는 방법에 대해 더 좋은 아이디어를 가지길 희망했습니다.ListBox를 사용하여 MVVM을 사용하여 TextBox를 탐색하십시오.

TextBox은 섹션을 포함합니다. [Secion1] 및 내비게이션을 돕기 위해 의 측면에 모든 섹션 목록이 포함 된 ListBox이 있습니다. 섹션 중 하나를 클릭하면 텍스트의 해당 부분으로 자동으로 이동합니다.

코드는 현재이 같은 같습니다

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은 적어도 두 가지 속성, 즉 SelectedSectionScrolledLine으로 확장되어야합니다. ScrolledLinePropertyChanged으로 올려야합니다. SelectedSection 세터 ScrolledLine을 변경해야합니다 :

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

3)이 두 가지 새로운 속성보기를 바인딩 :

아래

b XML - 네임 스페이스가 부착 된 행동입니다 # 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에서) 보기에서 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 개념의 view 및 viewModels를 결합하는 데 매우 중요합니다. AB가 많은 도움을 줄 수있는 많은 사례가 있습니다. – Snowbear

+0

그래, 다시 한 번 감사드립니다. 스노우 보드, 내 응용 프로그램이 확장 될 때 이것이 유용 할 수있는 더 많은 상황이있을 것이라 확신합니다. 귀하의 예제 코드에서 새로운 PropertyMetadata 안에 새 PropertyChangedCallback이 누락되었습니다. – eandersson

관련 문제