【问题标题】:Changing selected state of items in bound listbox更改绑定列表框中项目的选定状态
【发布时间】:2012-07-11 10:29:57
【问题描述】:

我正在尝试根据是否在项目绑定到的类中使用对象来更改绑定列表框中项目的选定状态,我似乎无法找到一种方法来做到这一点必须保持动态,因为对象可能会改变并因此在类的不同实例中使用:

  <Popup x:Name="ContextMenuPopup" Height="250" Width="300" Margin="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <Canvas Name="popupholder" Background="DarkSeaGreen" Height="250" Width="300" HorizontalAlignment="Center">
                <StackPanel Orientation="Vertical">
                <TextBlock Name="popupTitle" Text="Select Investments" Margin="20,0,0,0" FontFamily="Courier New" FontSize="22" HorizontalAlignment="Center" Foreground="Black" />
                <ListBox x:Name="investPicker" SelectionChanged="ListBox_SelectionChanged" LayoutUpdated="investPicker_LayoutUpdated" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Margin="10,20,0,0" SelectionMode="Multiple">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}" Width="100"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox> 
                    <Button Name="executeSelection" Content="Ok" Click="executeSelection_Click" Margin="40,5,0,0" VerticalAlignment="Bottom"/>
                </StackPanel>           
            </Canvas>
        </Popup>

后面的代码是:

        private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)
    {
        this.investPicker.ItemsSource = storedInvestments;

        foreach (Investment investment in investPicker.Items)
        {
            foreach (CardDataSet card in investment.attachedCards)
                if (card.ID == activeCard.ID)
                    VisualStateManager.GoToState((ListBoxItem) investPicker.Items[investment.ID -1], "Selected", true);
        }

        ContextMenuPopup.IsOpen = true;

    }

现在显然代码不起作用,因为它是从我的类到 ListBoxItem 的无效转换,有人知道我该怎么做吗?

【问题讨论】:

    标签: c# windows-phone-7 binding listbox listboxitem


    【解决方案1】:

    看起来你只会有一个选定的项目,那么这个怎么样:

    investPicker.SelectedItem = storedInvestments
        .FirstOrDefault(i => i.attachedCards.Any(c => c.Id == activeCard.ID));
    

    或者,如果您有多个:

    var matchingItems = storedInvestments
        .Where(i => i.attachedCards.Any(c => c.Id == activeCard.ID));
    
    foreach (var i in matchingItems)
        investPicker.SelectedItems.Add(i);
    

    [编辑]

    OP 不知道箭头运算符=&gt; 是什么意思,所以让我们澄清一下。它被称为 lambda 表达式,出于本次讨论的目的,您可以将其视为一个小的内联方法。

    这个表达式:

    i.attachedCards.Any(c => c.Id == activeCard.ID);
    

    可以理解为“i.attachedCards 是否包含 c.Id 等于 activeCard.ID 的任何 Card c”。

    c =&gt; c.Id == activeCard.ID 表示的方法也可以写成:

    static bool IsActiveCard(Card c) { return c.Id == activeCard.ID; }
    

    事实上,如果你要这样写,你可以将表达式更改为:

    i.attachedCards.Any(IsActiveCard);
    

    表达式的其余部分是对IEnumerable&lt;T&gt; 扩展方法Any 的调用,该方法评估attachedCards 序列中每个元素的方法,直到找到方法返回true 的元素,或者序列结束.如果找到元素则返回 true,否则返回 false。

    那么这个位:

    storedInvestments
        .FirstOrDefault(i => i.attachedCards.Any(c => c.Id == activeCard.ID));
    

    可以读作“给我第一个匹配的投资 i 在存储投资中 i.attachedCards 包含卡 c ...”等等。

    它在storedInvestments 序列中查找内部表达式返回true 的第一个元素。如果它没有找到任何东西,它会返回该类型的默认值(很可能是null,除非storedInvestmentsstruct)。

    我不会继续讨论技术细节,但如果您真的对这一切的工作原理感兴趣,Jon Skeet 写了一篇很棒的 series of articles 来介绍它的实际实现方式。强烈推荐。 :)

    【讨论】:

    • 像梦一样工作,非常感谢,我还是新手,所以我不知道 i => 实际做了什么,但它有效 :)
    • 我添加了一些解释性的东西,希望对您有所帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-04-04
    • 2020-11-23
    • 1970-01-01
    • 2012-10-11
    • 2021-04-16
    • 2017-07-15
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多