В таких ситуациях я обычно создаю прикрепленное поведение (в вашем случае это будет поведение, которое позволит синхронизировать прокручиваемую строку текстового поля), добавляю свойство в ViewModel (SourceData
), которое будет определять это присоединенное поведение и привязывать поведение к этому свойство.
Шаги, которые вы должны сделать в вашем случае (я полагаю, вы знаете, как создать вложенные свойства):
1) Создать прикрепленное поведение ScrolledLine
для текстового поля. Он должен поддерживать как минимум one-way
привязку. В обратном вызове присоединенного свойства вы прокрутите textBox (к которому привязано поведение) до line
. Ниже вы найдете краткий пример того, как реализовать такое поведение.
2) Ваш SourceData
должен быть расширен как минимум двумя свойствами: SelectedSection
и ScrolledLine
. ScrolledLine
должно быть повышение PropertyChanged
. 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
отныне.
P.S .: Вот пример того, как должно выглядеть ваше прикрепленное поведение:
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
}
}