2012-07-11 101 views
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> 

Thwe后面的代码是:

 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的无效投射,任何人都知道我可以如何这个?

回答

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不知道箭头运算符=>是什么意思,所以让我们澄清一下。它被称为lambda表达式,您可以将本文讨论的内容视为小型内联方法。

该表达式:

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

可以读作 “确实i.attachedCards包含任何卡c,对于它c.Id等于activeCard.ID”。

,说c => c.Id == activeCard.ID位表示也可以写成一个方法:

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

而事实上,如果你把它写的话,你可以在表达式更改为:

i.attachedCards.Any(IsActiveCard); 

表达式的其余部分是对IEnumerable<T>扩展方法Any的调用,该方法计算attachedCards序列中每个元素的方法,直到它找到方法返回true的元素或seque结束。如果它发现了一个元素,则它返回true,否则返回false。

然后,这一点:

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

可以读作“给我的第一个匹配的投资我在storedInvestments为其i.attachedCards包含卡C ......”等等。

它看起来在storedInvestments序列,其中所述内表达式返回true的第一个元素。如果没有发现任何东西,它返回类型的默认值(这很可能是null,除非storedInvestmentsstruct)。

我不会去上有关的技术细节,但如果你在这一切是如何工作很感兴趣,乔恩斯基特有它如何实际实施写一个伟大的series of articles。强烈推荐。:)

+0

作品像做梦一样,非常感谢你,我仍然在这个新的,所以我不知道我=>实际上做了,但我加了一些解释性的东西上,它的工作原理:) – Phil 2012-07-11 13:24:00

+0

,希望它有助于! – Rytmis 2012-07-12 10:09:07

相关问题