将列表视图项的字符串复制到文本框中

本文关键字:文本 复制 字符串 列表 视图 | 更新日期: 2023-09-27 18:29:17

所以我正在研究一个计算器,基本上是Windows版本的副本,作为训练练习。我已经实现了过去计算的历史,并被要求将这段历史从TextBox转换为Listview。我想做的是在单击它时将过去的一个计算复制回Calculator TextBox,就像在Windows计算器中一样。

我的列表视图代码:

<ListView Grid.Column="0" Grid.Row="1" Foreground="#616161" Name="history" Background="Transparent" 
          HorizontalAlignment="Stretch" BorderThickness="0" Margin="10,10,10,0">
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <EventSetter Event="MouseLeftButtonDown" Handler="RetrievePastCalculation" />
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

这是RetrievePastCalculation方法,但它不起作用,当我单击ListViewItem时没有任何反应.顺便说一下,我是 WPF 的新手。

private void RetrievePastCalculation(object sender, MouseButtonEventArgs e)
{
    innerTextBox.Text = history.SelectedItems.ToString();
}

这是我向ListView添加项目的地方,我认为它是相等按钮方法:

private void ButtonEquals_Click(object sender, RoutedEventArgs e)
{
    Calculator calculate = new Calculator();
    textBox.Text = calculate.Calculate(innerTextBox.Text);
    history.Items.Add(innerTextBox.Text + "=" + textBox.Text);
    innerTextBox.Clear();
}

将列表视图项的字符串复制到文本框中

history.SelectedItems是一个

集合,因此调用ToString它不会给你除了类型名称之外的任何内容。如果您在调试器中尝试它(您应该这样做(,您将看到它返回System.Windows.Controls.SelectedItemCollection .现在,此时可以通过以下两种方式之一解决问题:可以继续使用当前基于事件的方法,也可以使用绑定。

事件

使用事件,可以将处理程序挂接到添加到列表中的每个ListItemSelected事件:

private void ButtonEquals_Click(object sender, RoutedEventArgs e)
{
    Calculator calculate = new Calculator();
    textBox.Text = calculate.Calculate(innerTextBox.Text);
    var item = new ListViewItem();
    item.Content = innerTextBox.Text + "=" + textBox.Text;
    item.Selected += HistoryItem_Selected //hooks the handler to the 'Selected' event
    history.Items.Add(item);
    innerTextBox.Clear();
}

然后定义处理程序本身:

private void HistoryItem_Selected(object sender, RoutedEventArgs e)
{
   // here 'sender' will be the ListItem which you clicked on
   // but since it's an object we need to cast it first
   ListViewItem listItem = (ListViewItem)sender;
   // now all that's left is getting the text and assigning it to the textbox
   innerTextBox.Text = listItem.Content.ToString();
}

捆绑

代码量而言,绑定要简单得多,但学习曲线更陡峭。在这里,我们将指定一个绑定表达式,而不是直接设置 TextBox.Text 属性。这意味着该值将始终与绑定表达式的值相同。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <ListView Grid.Column="0" Grid.Row="0" Name="history" />
            <TextBox Text="{Binding ElementName=history, Path=SelectedItem.Content}" />
            <Button Name="ButtonEquals" Content="equals" Click="ButtonEquals_Click"/>
        </StackPanel>
    </Grid>
</Window>

我已经在一个新的 WPF 项目中运行了它,它按预期工作:文本框显示列表中单击的项中的任何文本。

需要注意的一点是,这两种解决方案都假定您将字符串分配给ListViewItem Content。如您所知,您可以将其他控件或任何对象分配给 UI ControlContent 属性(ListViewItem继承自 Control (。这就是为什么 ListViewItem.Add 方法采用类型 object 的参数,而不限于类型 string 的原因。如果在按钮单击事件处理程序中分配了字符串以外的任何内容,则上述两种情况都可能会中断。

可以将文本框的值绑定到列表视图的选定项。 下面是一个示例:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
  <ListView Grid.Column="0" Grid.Row="0" Foreground="#616161" Name="history" Background="Transparent" 
             HorizontalAlignment="Stretch" BorderThickness="0" Margin="10,10,10,0">
                <ListViewItem>Calc1</ListViewItem>
                <ListViewItem>Calc2</ListViewItem>
            </ListView>
            <TextBox Text="{Binding ElementName=history, Path=SelectedItem.Content}" />
</StackPanel>
</Page>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <ListView Grid.Column="0" Grid.Row="0" Foreground="#616161" Name="history" BorderThickness="1,1" Height="50" Width="200" SelectionChanged="history_SelectionChanged">
        <ListViewItem>
            <TextBlock> A ListView</TextBlock>
        </ListViewItem>
        <ListViewItem>
            with several
        </ListViewItem>
        <ListViewItem>
            items
        </ListViewItem>
    </ListView>
    <TextBox Grid.Row="1" Text="{Binding ElementName=history,Path=SelectedValue.Content}"
            BorderThickness="1,1" Height="50" Width="200"   />
</Grid>

最好使用 XAML 代码执行此操作。 尝试选择项目 0 和 1 以查看差异并了解列表框的工作原理。

现在将文本框绑定的文本替换为以下内容:

Text="{Binding ElementName=history,Path=SelectedValue.Content.Text}"

并查看项目 0 的输出。希望您能以更少的努力实现所需的输出。

现在您已经解释了整个问题,我认为您需要在 TextBox 的文本绑定中实现一个转换器。 像下面的文字

Text="{Binding ElementName=history,Path=SelectedValue.Content.Text,Converter={StaticResource mytextconverter}}"

并写下逻辑以根据"="字符提取部分文本。编写转换器类非常容易。 要编写转换器,请访问以下链接:

WPF 转换器示例