[英]c# How to get Listbox selection from Observable Collection
我什至没有正确地问过这个问题,我是C#的新手,但是试图帮助我14岁的儿子学习。 我已经创建了一个列表框,其中包含使用ObservableCollection创建的项目。 这是XAML:
<ListBox x:Name="listBox1" ItemsSource="{Binding}" Margin="105,205,886,63"
IsTabStop="True" SelectionChanged="PrintText"
ScrollViewer.VerticalScrollBarVisibility="Hidden" TabIndex="5" FontSize="36"
Background="Transparent" Foreground="#FF55B64C" FontFamily="Arabic Typesetting"
FontWeight="Bold" IsDoubleTapEnabled="False" SelectionMode="Single" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="blockNameList" Text="{Binding name}"/>
<TextBlock Text=" #"/>
<TextBlock Name="blockIdList" Text="{Binding id}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这是我创建列表框项目的方式:
var client = new HttpClient();
var uri = new Uri("http://theurlImusing");
Stream respStream2 = await client.GetStreamAsync(uri);
// DataContractJsonSerializer ser2 = new DataContractJsonSerializer(typeof(RootObject));
// RootObject feed2 = (RootObject)ser2.ReadObject(respStream2);
DataContractJsonSerializer ser = null;
ser = new DataContractJsonSerializer(typeof(ObservableCollection<RootObject>));
ObservableCollection<RootObject> feed2 = ser.ReadObject(respStream2) as ObservableCollection<RootObject>;
var cardList = new List<RootObject>();
foreach (RootObject returnfeed in feed2)
{
string cid = returnfeed.id;
string cardname = returnfeed.name;
listBox1.Items.Add(new RootObject { id=cid, name=cardname });
}
我以为我只使用列表框的SelectionChanged =“ PrintText”属性,这样当我单击列表框项时,它只会更改文本块的文本值。 最终,这就是我要做的所有事情……将文本块或文本框设置为等于在列表框中单击的“ id”值。
void PrintText(object sender, SelectionChangedEventArgs args)
{
//What do I put in here??
}
非常感谢您的见解! 我需要它!!
使用数据绑定更容易做到这一点。 您可以使用ElementName
绑定将TextBlock.Text
属性直接绑定到ListBox
:
<TextBox Text="{Binding ElementName=listBox1,Path=SelectedItem.id}" />
另外,如果您在ListBox上设置set SelectedValuePath="id"
,则绑定到SelectedValue
将为您提供“ id”属性:
<ListBox x:Name="listBox1" SelectedValuePath="id" ... />
<TextBox Text="{Binding ElementName=listBox1,Path=SelectedValue}" />
附带说明一下(正如@Rachel在评论中已经指出的那样):您最好只设置ItemsSource
,而不是循环遍历并手动添加每个项目。 您需要的是:
listBox1.ItemsSource = feed2;
编辑
好的,如果您想使用过程方法,请按以下步骤进行。 (没有人会推荐这种方法,尤其是在您学习/教学时。请尝试充分利用数据绑定和视图-视图模型分离。)
void PrintText(object sender, SelectionChangedEventArgs args)
{
var listBox = (ListBox)sender;
RootObject selectedItem = listBox.SelectedItem;
someTextBox.Text = selectedItem.id;
}
如果您要做的只是单击ListBox中的一项并使其显示在TextBox中,则不需要花哨的装订(在其他答案中)。 您只需在ListBox
XAML中添加MouseUp
事件:
MouseUp="ListBox1_MouseUp"
这将类似于您要使用的SelectionChanged
事件。
然后,在XAML页面中右键单击该函数名称,然后选择“转到定义”。 它将为您创建下一个功能:
private void ListBox1_MouseUp(object sender, MouseButtonEventArgs e)
{
}
只需在其中添加以使用sender
的SelectedItem
值更新所需的TextBox即可:
private void ListBox1_MouseUp(object sender, MouseButtonEventArgs e)
{
ListBox lstBox = (ListBox)sender;
ListBoxItem item = lstBox.SelectedItem;
if (item != null) // avoids exception when an empty line is clicked
{
someBox.Text = item.name;
someOtherBox.Text = item.id;
}
}
后来我发现,通过智能感知无法访问blockNameList
和blockIdList
,因为它们位于ListBox的DataTemplate中,因此我将someBox
和someOtherBox
引用为必须在someBox
之外添加到XAML的其他someBox
引用。 通过单击它,您不会在同一项目的ListBox内重写数据。 即使您可以到达模板的TextBlock来执行此操作,您也将只使用其自己的值来重写同一项目,因为它将是SelectedItem
!
即使有些人因为喜欢绑定所有内容而不建议使用此方法,并且在某些情况下,您希望进行绑定,以便页面上的控件由于依赖关系而更新(即,做一件事情导致另一件事情),发现单击按钮/项目/控件来更新某些内容的手动方法很好,并且可以避免所有接管WPF并使其过于复杂的模型/ MVVM BS。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.