C# 单击按钮获取所选ListBoxItem的名称

C# 单击按钮获取所选ListBoxItem的名称,c#,wpf,C#,Wpf,我是WPF/C#的新手,我正在尝试创建一个简单的sql查询应用程序来适应它。我的XAML中有一个列表框和相应的按钮: <ListBox Name="dbTables" Grid.Column="1" Grid.Row="2"> <ListBoxItem>Log</ListBoxItem> <ListBoxItem>DownloadRequest</ListBoxItem> <List

我是WPF/C#的新手,我正在尝试创建一个简单的sql查询应用程序来适应它。我的XAML中有一个列表框和相应的按钮:

<ListBox Name="dbTables" Grid.Column="1" Grid.Row="2">
        <ListBoxItem>Log</ListBoxItem>
        <ListBoxItem>DownloadRequest</ListBoxItem>
        <ListBoxItem>EmailRequest</ListBoxItem>
    </ListBox>

    <!-- View report button -->
    <Button x:Name="myButton" Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125" Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
但是,当输出CurItem时,它具有以下值:

CurItem=System.Windows.Controls.ListBoxItem:Log

当我尝试运行SQL查询时,它会抛出一个异常。我正努力让它成为现实
CurItem=Log


我尝试了几种不同的方法,但在没有附加对象定义的情况下,我似乎无法仅获取所选值的名称。

所选值是ListBoxItem,因此您可以将该值强制转换为ListBoxItem,然后使用Content属性:

ListBoxItem selItem = (ListBoxItem)dbTables.SelectedValue;

        Console.WriteLine(selItem.Content);

选定的值是ListBoxItem,因此可以将该值强制转换为ListBoxItem,然后使用Content属性:

ListBoxItem selItem = (ListBoxItem)dbTables.SelectedValue;

        Console.WriteLine(selItem.Content);

SelectedItem
返回列表框中当前选定的项目。由于您正在使用
ListBoxItem
s填充列表框,因此它将返回此结果。(顺便说一句,请注意,您的列表框会自动为其项目生成
ListBoxItem
容器-如果您查看可视化树,您会发现此
ListBox
包含
ListBoxItem
s,其中每个都包含一个
ListBoxItem
SelectedItem
包含生成的
Li的内容。)stBoxItem
,也就是说,您正在标记中创建的
列表boxItem
。)

SelectedValue
返回由
列表框指定的
SelectedItem
属性的值。SelectedValuePath
。如果没有给出
SelectedValuePath
,它将返回
SelectedItem
,因此,如果您不知道
SelectedValuePath
,那么这两者似乎是一样的。但是,如果您使用
个人
对象填充列表,并将
SelectedValuePath
设置为
名称
,则
SelectedValue
将包含所选个人的姓名,而不是对
个人
对象的引用

因此,在您的示例中,可以通过将
SelectedValuePath
设置为
“Content”
,使
SelectedValue
返回字符串,这是包含您正在使用的字符串的
ListBoxItem
的属性

您可以通过另一种方式来实现,即不显式创建
ListBoxItem
s,而只是用字符串填充
ListBox
。要做到这一点,您必须声明一个名称空间引用
mscorlib
,以便可以用XAML表示字符串对象,但一旦声明,结果很简单:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <DockPanel>  
    <ListBox DockPanel.Dock="Top" Margin="10" x:Name="test" SelectedValuePath="Length">
      <sys:String>Log</sys:String>
      <sys:String>DownloadRequest</sys:String>
      <sys:String>EmailRequest</sys:String>
    </ListBox>
    <TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedItem}"/>    
    <TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedValue}"/>    
  </DockPanel>
</Page>

日志
下载请求
电子邮件请求

SelectedItem
返回列表框中当前选定的项目。由于您正在使用
ListBoxItem
s填充列表框,因此它将返回此结果。(顺便说一句,请注意,您的列表框会自动为其项目生成
ListBoxItem
容器-如果您查看可视化树,您会发现此
ListBox
包含
ListBoxItem
s,其中每个都包含一个
ListBoxItem
SelectedItem
包含生成的
Li的内容。)stBoxItem
,也就是说,您正在标记中创建的
列表boxItem
。)

SelectedValue
返回由
列表框指定的
SelectedItem
属性的值。SelectedValuePath
。如果没有给出
SelectedValuePath
,它将返回
SelectedItem
,因此,如果您不知道
SelectedValuePath
,那么这两者似乎是一样的。但是,如果您使用
个人
对象填充列表,并将
SelectedValuePath
设置为
名称
,则
SelectedValue
将包含所选个人的姓名,而不是对
个人
对象的引用

因此,在您的示例中,可以通过将
SelectedValuePath
设置为
“Content”
,使
SelectedValue
返回字符串,这是包含您正在使用的字符串的
ListBoxItem
的属性

您可以通过另一种方式来实现,即不显式创建
ListBoxItem
s,而只是用字符串填充
ListBox
。要做到这一点,您必须声明一个名称空间引用
mscorlib
,以便可以用XAML表示字符串对象,但一旦声明,结果很简单:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <DockPanel>  
    <ListBox DockPanel.Dock="Top" Margin="10" x:Name="test" SelectedValuePath="Length">
      <sys:String>Log</sys:String>
      <sys:String>DownloadRequest</sys:String>
      <sys:String>EmailRequest</sys:String>
    </ListBox>
    <TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedItem}"/>    
    <TextBlock DockPanel.Dock="Top" Margin="10" Text="{Binding ElementName=test, Path=SelectedValue}"/>    
  </DockPanel>
</Page>

日志
下载请求
电子邮件请求

您是否尝试过设置此日志您是否尝试过设置此日志您知道为什么在这种简单的情况下,
SelectedValue
最终成为
ListBoxItem
?我的意思是,我们还有
SelectedItem
等等。@Matti Virkkunen:详细信息请参见我的答案。你知道为什么在这个简单的例子中
SelectedValue
最终成为
ListBoxItem
?我的意思是,我们还有
SelectedItem
等等。@Matti Virkkunen:详细内容请看我的答案。哇,太好了。我认为这仍然会创建ListBoxItem实例,对吗?所以有一些类型检查正在进行,以便您也可以使用其他对象,并且非ListBoxItems会自动包装到项目中?是的。所有items控件都将它们的项包装在一个容器中—这就是
ItemsControl.ItemContainerGenerator
所做的。如果您需要项目具有附加属性(例如,如果项目模板是一个
网格
,并且您希望设置
网格.行
网格.列
),则需要使用
项目容器样式
对其进行设置,而不是将其放入
项目模板
,这是您需要了解的主要原因。哇,很不错的。我认为这仍然会创建ListBoxItem实例,对吗?因此,需要进行一些类型检查,以便您也可以使用其他对象和非ListBoxItems