【问题标题】:UWP: Updating a Background in an ItemTemplate based on a conditionUWP:根据条件更新 ItemTemplate 中的背景
【发布时间】:2017-04-07 17:18:22
【问题描述】:

在 UWP 项目中,ListView 绑定到集合 player 对象。每个player 对象都有一个属性,例如HighScoreListViewItemTemplate 显示每个玩家的 HighScore。我想更改ItemTemplateItemTemplateGridBackground,当它的HighScore 匹配BiggestScore(页面DataContext 的属性)时。这代表了所有玩家的最大分数。 BiggestScore 在设置HighScore 后更新。

有什么想法可以实现这一点吗?

这里有一些示例代码,希望能说明各个部分。

XAML:

<Grid x:Name="root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView x:Name="lvwPlayers" ItemsSource="{Binding Players}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="grdHighScore" Background="Yellow">
                    <TextBlock Text="{Binding HighScore}"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

代码隐藏:

    public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        var allPlayers = new AllPlayers();

        allPlayers.Players.Add(new Player(100));
        allPlayers.Players.Add(new Player(112));
        allPlayers.Players.Add(new Player(1160));
        allPlayers.Players.Add(new Player(122));

        this.DataContext = allPlayers;
    }
}

玩家:

    public class Player : INotifyPropertyChanged
{
    protected void OnPropertyChanged([CallerMemberName] string caller = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public Player( int high)
    {
        HighScore = high;
    }

    private int _highScore;
    public int HighScore
    {
        get { return _highScore; }
        set
        {
            _highScore = value;
            OnPropertyChanged();
        }
    }
}

所有玩家:

   public class AllPlayers : INotifyPropertyChanged
{
    public ObservableCollection<Player> Players { get; set; }

    public AllPlayers()
    {
        Players = new ObservableCollection<Player>();
    }

    protected void OnPropertyChanged([CallerMemberName] string caller = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(caller));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void ChangeScore(int playerIndex, int highScore)
    {
        Players[playerIndex].HighScore = highScore;
    }

    private void UpdateBiggestScore()
    {
        BiggestScore = (from player in Players select player.HighScore).Max();
    }

    private int _biggestScore;
    public int BiggestScore
    {
        get { return _biggestScore; }
        set
        {
            _biggestScore = value;

            OnPropertyChanged();
        }
    }
}

【问题讨论】:

    标签: c# xaml uwp win-universal-app uwp-xaml


    【解决方案1】:

    在您的 DataContext 中创建属性,说明 HighScore 是否大于 BiggestScore,例如。布尔是最大的

    绑定它:

    Background={Binding IsBiggest, Converter=HighScoreToColorConverter}
    

    YourConverter 可能类似于:

    public class HighScoreToColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var isBiggest = (bool)value;
            var color = isBiggest ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Yellow);
            return color;
        }
    
    public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            var color = value as SolidColorBrush;
            if (color != null)
            {
                return color == new SolidColorBrush(Colors.Red);
            }
    
            return false;
        }
    }
    

    【讨论】:

    • 嗨@RTDev,感谢您的回复。如果您建议将 IsBiggest 放在 player' class, then this won't work as player` 对象上,则无法访问 Pages 的 `DataContext,即无法获得 BiggestScore,因此无法评估 IsBiggest。有没有办法让 BiggestScore 进入转换器?
    • 嗯,你说得对。不确定您是否可以这样做,而无需避免手动仅保留一个玩家将 IsBiggest 属性设置为 true。 Conver 只接受一个值参数,因此如果不将 HighestValue 存储在静态对象的某个静态属性中并从 Converters ctor 引用它以与当前值进行比较,则无法在此处进行任何比较(HighestScore 与当前 Player.HighScore),但是这不会是最好的解决方案。
    • 遗憾的是,与 WPF 相比,UWP 的限制如此之大。
    【解决方案2】:

    您可以将背景颜色作为属性添加到您的播放器

    private SolidColorBrush _backgroundColor = new SolidColorBrush(Colors.Yellow);
    public SolidColorBrush BackgroundColor
    {
        get { return _backgroundColor; }
        set
        {
            _backgroundColor= value;
            OnPropertyChanged();
        }
    }
    

    并将其绑定到网格的背景

    <Grid x:Name="grdHighScore" Background="{Binding BackgroundColor}">
        <TextBlock Text="{Binding HighScore}"/>
    </Grid>
    

    更新最大分数时,获取分数最高的玩家对象并更新背景。同时将所有其他玩家的背景改回黄色。

    【讨论】:

    • 嗨@Thomas Schneiter,感谢您的回复。我确实想到了类似的东西,但希望有一个“更清洁”的解决方案,我不必遍历所有其他玩家并“重置”那里的背景。
    猜你喜欢
    • 2014-10-05
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多