gpt4 book ai didi

c# - 使用 ListBox 导航带有 MVVM 的 TextBox

转载 作者:行者123 更新时间:2023-11-30 22:40:56 25 4
gpt4 key购买 nike

我正在尝试将以下函数 listView_SelectionChanged 移出代码隐藏并直接在我的 ViewModel 中处理它(或直接作为 XAML)。我希望有人对如何实现它有更好的想法。

TextBox包含部分,例如[Secion1] 为了帮助导航,我有一个 ListBox在包含所有部分列表的 TextBox 一侧。如果您单击其中一个部分,它将自动跳转到文本的该部分。

目前的代码看起来是这样的:

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
}
}

最佳答案

在这种情况下,我通常会创建一个附加行为(在你的情况下,它将是一个允许同步文本框滚动行的行为),在 ViewModel (SourceData) 中添加属性,这将决定附加行为并将行为绑定(bind)到此属性。

在您的情况下您应该执行的步骤(我假设您知道如何创建附加属性):

1) 为文本框创建附加行为ScrolledLine。它应该至少支持单向 绑定(bind)。在附加属性回调中,您将滚动文本框(行为附加到其上)到 line。您将在下面找到如何实现此类行为的快速示例。

2) 您的 SourceData 应该至少扩展两个属性:SelectedSectionScrolledLineScrolledLine 应该引发 PropertyChangedSelectedSection setter 应更改 ScrolledLine:

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

3) 将您的 View 绑定(bind)到这两个新属性:

b 下面是来自 #1

的附加行为的 xml 命名空间
<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) 从 View 中删除您的 listView_SelectionChanged 事件处理程序。从现在开始,除了 InitializeComponent 之外,您的 View 不应包含任何代码。

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
}
}

关于c# - 使用 ListBox 导航带有 MVVM 的 TextBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4983946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com