2010-01-03 54 views
0

这是我要做的事情的要点。如何根据类属性过滤不同的东西?

继承人我的英雄职业:

namespace TomeOfNewerth_WPF_ 
{ 
    public enum HeroType 
    { 
     Agility, 
     Strength, 
     Intelligence 
    } 

    public enum AttackType 
    { 
     Melee, 
     Ranged, 
    } 

    class Hero 
    { 
     public string Faction; 
     public string Name; 
     public HeroType HeroType; 
     public string Backstory; 
     public double MinimumDamage; 
     public double MaximumDamage; 
     public double Armor; 
     public double MoveSpeed; 
     public AttackType AttackType; 
     public double AttackRange; 
     public double AttackRate; 
     public int Strength; 
     public int Agility; 
     public int Intelligence; 
     public string DOTAVersion; 

     //Default constructer required for XML serialization. 
     public Hero() 
     { } 

     /// <summary> 
     /// This method returns a hero full of the necessary information. 
     /// </summary> 
     /// <param name="Name">Name of the hero.</param> 
     /// <returns>Returns an instace of the Hero class chock full of information.</returns> 
     public Hero GetHero(string Name) 
     { 
      Hero NewHero = new Hero(); 

      NewHero.Faction = "Legion"; 
      NewHero.Name = "Andromeda"; 
      //Yada yada yada. I have to complete this, so disregard it. 

      return NewHero; 
     } 
    } 
} 

该类的每个属性是一个XML元素。我已经手动将所有信息列表到一个XML文件中,这样我就可以将它反序列化到Hero类中,并将实例转发到任何需要的地方。

有一个用例,我不能真正得到我的头。

我有两个按钮,ViewGood和ViewEvil。

英雄级别上有一个名为Faction的属性,我必须筛选出哪些英雄拥有良好,哪些英雄拥有邪恶。

我在想什么做的:

  1. 我有一个周期的方法 通过XML中的每个节点和 返回一个包含所有 匹配其主人公名称的列表被要求的HEROTYPE。

  2. 使用列表,然后我就可以做 一个foreach和因为形式 与x上 有一个图像控制所有英雄:名称设置为英雄 名字,我可以做一个.Visibilty = 能见度。假设为 为 列表中的每个英雄名称。有效隐藏不在列表中的每个图像控件 。

我给你们的问题是,我在做什么完全迟钝的事情?我真的想花费额外的时间,并使这个程序有很好的干净的代码,因为我想学习比什么都重要。

正如我父亲所说,'坏习惯很容易学习,这是强奸你的好习惯。'

谢谢。 :)

+0

我想知道为什么有些人低估了我的问题。太多的词让你阅读? – 2010-01-04 00:15:35

+0

我也不知道 - 它不是一个不合理的问题 – Murph 2010-01-04 08:52:11

回答

4

我不明白。你想要一个由属性过滤的列表?

是否这样?

List<Hero> heroes = GetYourHeroes(); 
var goodGuys = heroes.Where(hero => hero.Faction == "Jedi"); 

编辑回答评论:

你二线相当于做一个foreach并询问是否hero.Faction == “绝”

更多或更少,是的。对于大多数目的来说,它的行为将是相同的,但底层的LINQ表现方式完全不同。如果你喜欢这个语法,我建议你阅读它,或者检查本网站上的LINQ问题。

主要可以咬你的区别是这是默认的懒惰。

Where(hero => hero.Faction == "Jedi")返回IEnumerable<Hero>,也不会真正做你想做的,除非你真的遍历枚举,通过手动或结果转换成一个列表:

Where(hero => hero.Faction == "Jedi").ToList()可能会做你有望在了什么第一名:这给你一个已经表示过滤结果的列表。

尽管如此,它还是很有用的,例如当你构建和嵌套多个这样的“查询”时。

+0

嗨Pap,本的答案使用了一种叫做LINQ的东西,它基本上允许你对对象集合执行查询。这对你正在做的事情是完美的。 – 2010-01-03 23:42:34

+0

嗨,本杰明。你会第二行相当于做一个foreach并询问是否hero.Faction =“Jedi”?如果是这样,那很SEXY。 – 2010-01-03 23:43:36

+0

结果是一样的,但它以更优化的方式实现,所以它的性能会更好。或者至少我认为这是! – 2010-01-03 23:55:11

1

在WPF中这样做的一个简单方法是使用CollectionView而不是原始列表作为ItemsSource。然后您可以对此设置一个过滤器,并且您的列表控件将只显示通过过滤器的项目。

然而,这听起来像你直接添加图像控件添加到面板(画布?),而不是使用列表控制。在这种情况下,迭代Image控件并设置其可见性是一种方法。另一种方法是创建一个视图模型类,该视图模型类使用诸如可见性之类的显示属性来增强Hero类,并在用户选择不同的视图按钮时更新该可见性。然后,Image控件可以将其可见性数据绑定到视图模型可见性。在视图模型中执行此操作而不是直接操作图像控件的优点是可测试性:对于这样的简单案例来说不是什么大问题,但对于复杂的应用程序来说这一点越来越重要。顺便说一下,如果您目前手动添加图片,但您的设计尚未设置完毕,我强烈建议使用ItemsControl来处理集合的显示。 (请记住,ListBox不仅仅是一个垂直堆栈:你可以用它来显示你选择的任何布局的东西。)这将消除很多乏味的迭代代码!

0

如果你不打算使用使用CollectionView(有利弊),另一种方式来处理这个问题的itowlson的建议是通过添加IsVisible属性的类,然后实施INotifyPropertyChanged。在WPF然后支持显示/隐藏是非常容易的:

<DataTemplate DataType="{x:Type local:Hero}"> 
    <StackPanel Orientation="Horizontal" IsVisible="{Binding IsVisible}"> 
     <TextBlock Text="{Binding Faction}"/> 
     <TextBlock Text="{Binding Name}"/> 
     ... etc. 
    </StackPanel> 
</DataTemplate> 

<ListBox ItemsSource="{Binding MyDataSource.HeroesCollection}"/> 

(你可能会使用一个Grid,而不是一个StackPanel;这只是显示了Hero对象DataTemplate可能是什么样子。)

IsVisible属性必须是Visibility类型,而不是布尔值,这很重要,除非您想实现一个值转换器来将true转换为Visibility.VisiblefalseVisibility.Collapsed,如this guy did

一旦你这样做,在做这样的事情:

foreach (Hero h in HeroesCollection) 
{ 
    h.IsVisible = h.Faction == selectedFaction 
     ? Visiblity.Visible 
     : Visibility.Collapsed; 
} 

会像魔术。 (如果你已经实现了INotifyPropertyChanged。如果你没有,没有任何事情会发生,因为UI不会知道Visibility属性发生了变化。)