我试图将以下函数listView_SelectionChanged
从代码隐藏中移除,并直接在我的ViewModel
内(或直接作为XAML)处理它。我希望有人可能对如何实现这一点有更好的了解。
TextBox包含章节,例如[Secion1]
并帮助导航我在TextBox
一侧有一个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
}
}
答案 0 :(得分:3)
在这种情况下,我通常会创建一个附加行为(在您的情况下,它将是一个允许同步文本框滚动行的行为),在ViewModel(SourceData
)中添加属性,该属性将规定附加行为和绑定行为这个属性。
您应该做的步骤(我假设您知道如何创建附加属性):
1)为文本框创建附加行为ScrolledLine
。它应该至少支持one-way
绑定。在附加属性回调中,您将textBox(附加到哪个行为)滚动到line
。您将在下面找到如何实现此类行为的快速示例。
2)您的SourceData
应至少使用两个属性进行扩展:SelectedSection
和ScrolledLine
。 ScrolledLine
应该提出PropertyChanged
。 SelectedSection
setter应更改ScrolledLine
:
private SectionData _selectedSection;
public SectionData SelectedSection
{
get { return _selectedSection; }
set
{
_selectedSection = value;
if (_selectedSection != null) SelectedLine = _selectedSection.Line;
}
}
3)将您的观点绑定到这两个新属性:
下面的 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)从视图中删除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
}
}