繁体   English   中英

c#如何从Observable集合中获取列表框选择

[英]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)
{
}

只需在其中添加以使用senderSelectedItem值更新所需的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;
    }
}

后来我发现,通过智能感知无法访问blockNameListblockIdList ,因为它们位于ListBox的DataTemplate中,因此我将someBoxsomeOtherBox引用为必须在someBox之外添加到XAML的其他someBox引用。 通过单击它,您不会在同一项目的ListBox内重写数据。 即使您可以到达模板的TextBlock来执行此操作,您也将只使用其自己的值来重写同一项目,因为它将是SelectedItem

即使有些人因为喜欢绑定所有内容而不建议使用此方法,并且在某些情况下,您希望进行绑定,以便页面上的控件由于依赖关系而更新(即,做一件事情导致另一件事情),发现单击按钮/项目/控件来更新某些内容的手动方法很好,并且可以避免所有接管WPF并使其过于复杂的模型/ MVVM BS。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM