将 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 Control
的 Content
属性(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:
编写转换器
所以我正在研究计算器,基本上是 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 Control
的 Content
属性(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:
编写转换器