将 ListViewItem 的字符串复制到 TextBox 中

Copy String of a ListViewItem into a TextBox

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

我的 ListViewCode:

<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 的地方,我认为是 Equal 按钮方法:

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 是一个 collection,所以在它上面调用 ToString 除了类型的名称之外不会给你任何东西。如果你在调试器中尝试它(你应该这样做),你会看到它 returns System.Windows.Controls.SelectedItemCollection。现在,此时您可以通过以下两种方式之一解决您的问题:您可以继续使用当前的 event-based 方法,或者您可以使用绑定。

事件

对于事件,您可以为添加到列表中的每个 ListItem 挂钩一个处理程序到 Selected 事件:

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 类型之一的原因。如果您在按钮单击事件处理程序中分配了字符串以外的任何内容,则上述两种情况都可能会中断。

您可以将 TextBox 的值绑定到 ListView 的 SelectedItem。这是一个例子:

<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 代码。尝试 select 项 0 和 1 以查看差异并了解列表框的工作原理。

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

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

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

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

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

并写下一个逻辑,根据'='字符提取一部分文本。写一个转换器非常容易class。按照以下 link:

编写转换器

WPF Converter example