C#WPF:列表框,通过拖动来选择文本
本文关键字:拖动 选择 文本 列表 C#WPF | 更新日期: 2023-09-27 18:00:57
我需要创建一个支持两个功能的WPF ListBox:
内容转换器绑定:
ListBox中的项需要传递给一个转换器,该转换器将这些项转换为文本格式。
以允许用户从ListBox项目中选择和复制文本的方式显示项目
我需要每个ListBox项目的文本都是可选的。用户希望使用鼠标拖动来选择部分元素,以便将文本复制到剪贴板。
我实现了[this复制/粘贴解决方案][1],但它不允许用户选择ListBox项文本的一部分,而是支持复制整个文本。
我可以使用转换器创建一个ListBox,但我不知道如何将转换后的文本放入一个控件中,让用户选择显示的文本。这是我所拥有的:
<ListBox Name="FinishedTestErrorsListBox"
FontSize="12"
ItemsSource="{Binding Path=SelectedComparisonResult.TestFailItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Converter={StaticResource testFailItemConverter}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我已经尝试将TextBox添加到DataTemplate中,如下所示。。。
<TextBlock Text="{Binding Converter={StaticResource testFailItemConverter}}"/>
但这会产生运行时错误,这是由于向转换器发送了错误类型的对象而导致的。我知道我在这里没有正确设置转换器绑定,尽管我没有很好地理解我应该如何在这里设置绑定,或者为什么这会导致错误。
所以,我的问题是:
我可以使用什么内容容器让用户从各个ListBox项目中选择文本
感谢您的帮助,
Charlie
编辑
这是转换器代码。。。
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ITestFailItem i = (ITestFailItem)value;
return i.Itemize();
}
编辑2
当ListBox首次初始化时,会引发以下运行时错误:
An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Provide value on 'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an exception
编辑3
罪魁祸首是我从原始代码片段中省略的一行代码,因为我认为它无关紧要——一路上我学到了很好的教训!
扩展问题
为什么以下代码段会导致错误?如何实现使文本框跨越整个包含网格的预期效果?
<TextBox Width="*"
Text="{Binding Path=., Converter={StaticResource testFailItemConverter}}"/>
试试这个。TextBlocks不支持文本选择,但TextBoxes支持。你只需要将其设为只读,这样用户就不能修改文本,并更改其边框厚度和背景,使其看起来像标签:
<ListBox Name="FinishedTestErrorsListBox"
FontSize="12"
ItemsSource="{Binding Path=SelectedComparisonResult.TestFailItems}">
<ListBox.Resources>
<converter:TestFailItemConverter x:Key="testFailItemConverter" />
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=.,
Converter={StaticResource testFailItemConverter},
Mode=OneWay}"
BorderThickness="0"
Background="Transparent"
IsReadOnly="True"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
您尝试过TextBox吗?您可以在文本框中选择文本。路径必须更改为Path=.
<TextBox Text="{Binding Path=., Converter={StaticResource testFailItemConverter}}" />
没有太多代码可供使用,但这段代码对我有效:
xaml:
<Window x:Class="StackOverflowTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:StackOverflowTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<s:TestFailItemConverter x:Key="testFailItemConverter" />
</Window.Resources>
<Grid>
<ListBox Name="FinishedTestErrorsListBox"
FontSize="12"
ItemsSource="{Binding Path=SelectedComparisonResult.TestFailItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<ContentControl Content="{Binding Converter={StaticResource testFailItemConverter}}"/>-->
<TextBox Text="{Binding Path=., Converter={StaticResource testFailItemConverter}}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
型号代码:
public class Dummy
{
public ObservableCollection<string> TestFailItems { get; set; }
public Dummy()
{
TestFailItems = new ObservableCollection<string>(new List<string> { "a", "b" });
}
}
public class Model
{
public Dummy SelectedComparisonResult { get; set; }
public Model()
{
SelectedComparisonResult = new Dummy();
}
}
转换器代码:
public class TestFailItemConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return "aa";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}