【问题标题】:WPF binding a property to a list of objectsWPF 将属性绑定到对象列表
【发布时间】:2014-07-21 03:39:08
【问题描述】:

我需要一些帮助来解决我遇到的一个简单的 XAML 绑定问题。

我使用 MVVM 模式和 2 个类。卡和板。我已经用卡片创建了一个模型。 Card 类仅由两个属性组成。

  1. 我卡的价值。
  2. 我的卡的状态(下行或上行)。该板包含一张卡片列表。
public class Card
{
    public int Value { get; private set; }
    public bool Upside { get; set; }

    public Card(int value)
    {
        this.Value = value;
    }
}

class Board
{
    private List<Card> _cardList = new List<Card>();
    public List<Card> CardList
    {
        get
        {
            return _cardList;
        }
        set
        {
            if (_cardList == value)
            {
                return;
            }
            _cardList = value;
            raisePropertyChanged("CardList");
        }
    }

    public void Initialize()
    { 
       // Initialization of the card list
    }

    public void FlipCard()
    {
       // The rules and actions of my game
    }
}

之后,我将所有INotifyPropertyChanged 内容添加到我的卡片和棋盘属性中。我不会向您展示代码以尽可能保持清晰。

在我的ViewModel 我只公开这个:

public Board GameBoard { get; set; }

当然,我还有很多其他的方法、属性和命令,但没有关于卡片的。我的游戏规则和我的牌都在我的棋盘课上。我的 ViewModel 只公开特定于我的 XAML 设计的类。

在我的 XAML 文件中,我有类似的内容。卡片是一个简单的矩形。我只需要用正确的转换器将我的卡的值与 Fill 属性绑定。我的想法是我只公开我的董事会,所以我需要写一些类似的东西

Fill="{Binding **GameBoard.CardList[0]** 

我不在运行时生成矩形。现在我的板上有 4 张卡,然后我写了 4 次矩形代码并硬编码了 4 次以 01、02、03、04 结尾的名称。我在这里只给你看 01:

<Window.Resources>
    <me:CardFillConverter x:Key="CardConverter"/>
</Window.Resources>

<Rectangle x:Name="Card01" Fill="{Binding ??? Converter={StaticResource CardConverter}}" ... />

什么是正确的绑定?

【问题讨论】:

  • @Alex 感谢您的更正

标签: c# wpf xaml mvvm


【解决方案1】:

在转换器中发挥你的作用。

<Rectangle x:Name="Card01" Fill="{Binding GameBoard.CardList Converter={StaticResource CardConverter} ConverterParameter = 0}" ... />

【讨论】:

    【解决方案2】:

    如果您的视图模型中有卡片列表,那么您可能必须以某种方式将它们全部显示在您的视图中?用索引器一一获取它们似乎没有意义。那么你也许应该使用类似的东西:

    <ItemsControl ItemsSource="{Binding CardList}">
     <ItemsControl.ItemTemplate>
            <DataTemplate>
              <Rectangle Fill="{Binding, Converter={StaticResource CardConverter}}"/>
            </DataTemplate>
     </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    【讨论】:

      【解决方案3】:

      给你

      您可以利用ItemsControl 并为卡片的外观和行为指定数据模板,而不是对卡片进行硬编码

      <ItemsControl ItemsSource="{Binding GameBoard.CardList}">
          <ItemsControl.ItemTemplate>
              <DataTemplate>
                  <Rectangle Fill="{Binding Value,Converter={StaticResource CardConverter}}"/>
              </DataTemplate>
          </ItemsControl.ItemTemplate>
      </ItemsControl>
      

      您也可以选择应用ItemsPanelTemplate 来定义卡片放置布局

      例如

      <ItemsControl ItemsSource="{Binding GameBoard.CardList}">
          <ItemsControl.ItemsPanel>
              <ItemsPanelTemplate>
                  <WrapPanel IsItemsHost="True" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
          <ItemsControl.ItemTemplate>
              <DataTemplate>
                  <Rectangle Fill="{Binding Value,Converter={StaticResource CardConverter}}" />
              </DataTemplate>
          </ItemsControl.ItemTemplate>
      </ItemsControl>
      

      【讨论】: