0

アイテムがバインドされているクラスでオブジェクトが使用されているかどうかに基づいて、バインドされたリストボックス内のアイテムの選択状態を変更しようとしていますが、それを行う方法が見つからないようで、そのままにしておく必要がありますオブジェクトが変更される可能性があり、クラスのさまざまなインスタンスで使用される可能性があるため、動的です。

  <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 への無効なキャストとして機能しません。これを行う方法を知っている人はいますか?

4

1 に答える 1

1

選択した項目が 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は矢印演算子の意味を知らなかった=>ので、少し明確にしましょう。これはラムダ式と呼ばれ、この説明では小さなインライン メソッドと考えることができます。

この式:

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

「i.attachedCards には、c.Id が activeCard.ID と等しいカード c が含まれていますか」と読むことができます。

と言うビットc => c.Id == activeCard.IDは、次のように書くこともできるメソッドを示します。

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

実際、そのように書くと、式を次のように変更できます。

i.attachedCards.Any(IsActiveCard);

式の残りの部分はIEnumerable<T>拡張メソッドの呼び出しであり、メソッドが true を返す要素が見つかるか、シーケンスが終了するまで、シーケンスAny内のすべての要素のメソッドを評価します。attachedCards要素が見つかった場合は true を返し、見つからなかった場合は false を返します。

次に、このビット:

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

「i.attachedCards にカード c が含まれる、storedInvestments 内の最初に一致する投資 i をください...」などと読むことができます。

storedInvestments内部式が true を返すシーケンス内の最初の要素を探します。何も見つからない場合は、型のデフォルト値を返します (が anullでない限り、である可能性が高い)。storedInvestmentsstruct

技術的な詳細については説明しませんが、これらすべてがどのように機能するかに本当に興味がある場合は、Jon Skeet が実際にどのように実装されているかについて素晴らしい一連の記事を書いています。強くお勧めします。:)

于 2012-07-11T10:39:19.430 に答える