我需要创建一个支持两个功能的WPF ListBox:
内容转换器绑定:
需要将ListBox中的项目传递给将项目转换为文本格式的转换器。
以允许用户从ListBox项目中选择和复制文本的方式显示项目
我需要每个ListBox项的文本是可选择的。用户希望使用鼠标拖动选择元素的一部分,以便将文本复制到剪贴板。
我实现了[此复制/粘贴解决方案] [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项目中选择文字?
感谢您的帮助,
查理
修改
这是转换器代码......
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}}"/>
答案 0 :(得分:1)
试试这个。 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>
答案 1 :(得分:1)
你试过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;
}
}