首页 > 解决方案 > 具有自定义视图的 Xamarin 集合视图

问题描述

我正在尝试使用单独的自定义视图单元格(FightCards)获取集合视图。当我使用附加的代码时,我得到了正确的外观,卡片放在一边。当我单击单元格时,视图应该更改背景颜色并更新赢/输计数。现在,它承认该单元格被单击并更新剩余的战斗机标签,但不更新单元格。

ui长什么样子在此处输入图像描述

任何帮助,将不胜感激。

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Tournaments.Views.FighterCard">
    <ContentView.Content>
     <StackLayout Padding="5">
            <Label x:Name="CardNumberText" Text="{Binding CardNumber}" HorizontalTextAlignment="End"/>
            <Label x:Name="NameText" Text="{Binding Name}" />
            <StackLayout Orientation="Horizontal">
                <Label x:Name="WinsText" Text="{Binding Wins}" />
                <Label x:Name="LosesText" Text="{Binding Losses}" />
            </StackLayout>
        </StackLayout>   
    </ContentView.Content>
</ContentView>

public partial class FighterCard : ContentView
{
    Model.Pairing Pair => Card.Pairings.Last();

    public static readonly BindableProperty CardProperty =
         BindableProperty.Create(nameof(Card), typeof(Model.FighterCard), typeof(Model.FighterCard), propertyChanged: CardChanged);

    public Model.FighterCard Card
    {
        get => (Model.FighterCard)GetValue(CardProperty);
        set
        {
            SetValue(CardProperty, value);
            OnCardSet();
        }
    }

    private static void CardChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var card = (FighterCard)bindable;
        card.Card = (Model.FighterCard)newValue;
    }

    public FighterCard()
    {
        InitializeComponent();
    }

    public void SetWinner()
    {
        Pair.SetWinner(Card);
        UpdateBackground();
    }

    void OnCardSet()
    {
        Debug.WriteLine($"Number of Pairs: {Card.Pairings.Count}");
        CardNumberText.Text = Card.CardNumber.ToString();
        NameText.Text = Card.Name;
        WinsText.Text = Card.NumberOfWins().ToString();
        LosesText.Text = Card.NumberOfLosses().ToString();
        UpdateBackground();
    }

    void UpdateBackground()
    {
        var result = Pair.ResultForFighter(Card);
        switch (result)
        {
            case Model.Pairing.BoutResult.Win:
                BackgroundColor = Color.Green;
                break;
            case Model.Pairing.BoutResult.Lose:
            case Model.Pairing.BoutResult.DoubleKill:
                BackgroundColor = Color.Red;
                break;
            default:
                BackgroundColor = Color.White;
                break;
        }
    }

    void OnTapped(object sender, EventArgs e)
    {
        Pair.SetWinner(Card);
        UpdateBackground();
        MessagingCenter.Send(this, "ResultReported", Card);
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:Tournaments.Views"
             x:Class="Tournaments.Views.ActiveTournamentPage">
    <ContentPage.Content>
        <StackLayout>
            <Label x:Name="RoundLabel" HorizontalTextAlignment="Center"></Label>
            <CollectionView x:Name="PairList"
                            SelectionMode="Single"
                            SelectionChanged="OnCardSelectionChanged">
         
               
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical" Span="2"/>
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>  
                        <views:FighterCard Card="{Binding .}"/>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>


            <Label x:Name="FightersInListLabel" Text="Fighters in list 1"></Label>
            <Label x:Name="PairsToFightLabel" Text="Pairs still to fight 2"></Label>
            <Button x:Name="EndRoundButton"
                    Text="End Round"
                    Clicked="OnEndRound"></Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

public partial class ActiveTournamentPage : ContentPage
{
    TournamentEngine Tournament;
    List<Pairing> Pairs;

    FighterCard _SelectedItem;
    public FighterCard SelectedItem { get; set; }
    public ActiveTournamentPage(Tournament tournament)
    {
        InitializeComponent();
        BindingContext = this;
        Tournament = new TournamentEngine(tournament);

        Tournament.StartRound();
        Pairs = Tournament.GenerateRound();
        UpdateUI();

        MessagingCenter.Subscribe<FighterCard, Model.FighterCard>(this, "ResultReported", OnResultReported);
    }

    void UpdateUI()
    {
        PairList.ItemsSource = Pairs.SelectMany(p => new List<Model.FighterCard>{ p.FighterA, p.FighterB});
        RoundLabel.Text = $"Round {Tournament.CurrentRound}";
        FightersInListLabel.Text = $"Fighters in list {Tournament.FightersInList}";
        UpdateFightersToFightLabel();
    }

    void OnEndRound(object sender, EventArgs args)
    {
        Pairs = Tournament.GenerateRound();
        UpdateUI();
    }

    void UpdateFightersToFightLabel()
    {
        var count = 0;
        foreach (var pair in Pairs)
        {
            if (!pair.HasPairFought())
                count += 1;
        }

        PairsToFightLabel.Text = $"Pairs still to fight: {count}";
        EndRoundButton.IsEnabled = (count == 0);
    }

    void OnResultReported(FighterCard cardView, Model.FighterCard fighterCard)
    {
        //UpdateFightersToFightLabel();
    }

    void OnCardSelectionChanged(object sender, SelectionChangedEventArgs e) {
        var fightCard = e.CurrentSelection.FirstOrDefault() as Model.FighterCard;
        fightCard.Pairings.Last().SetWinner(fightCard);
        UpdateFightersToFightLabel();
    }


    public ICommand FighterSelected
    {
        get
        {
            return new Command(_ =>
            {

                SelectedItem?.SetWinner();
                UpdateFightersToFightLabel();
                SelectedItem = null;
            });
        }
    }

}

标签: xamarin.formscollectionview

解决方案


推荐阅读