如何正确绑定 ListView 以便它的项目可以接收背景值?

How to properly bind a ListView so that it's items can receive a background value?

我目前正在开发一个小型视频扑克应用程序,部分原因是它很有趣,而且我需要一个学校项目。

除非我遗漏了什么,否则我的逻辑应该完成,但是现在,当我将注意力转向应用程序的 UI 方面时,我遇到了障碍。

我 need/want 我的 ListView 要做的是:

到目前为止我已经 "some" 成功了,这意味着我已经能够让它工作,这样我就可以 select 通过鼠标点击一个项目,然后颜色改变,但是我无法通过将 SelectedItem 更改为获胜手来使其工作。

我已经尝试了几乎所有我能想到的方法,但我已经走到了死胡同。 我相当确定它是通过绑定数据以某种方式实现的,但到目前为止我的所有努力都失败了。在数据绑定 XAML 元素方面,我仍然缺乏相当多的知识和经验。

如果这里有人可以帮助我 neat/clean/efficient 实现这一目标的方法,将不胜感激。

XAML:

<ListView x:Name="lvTest" HorizontalAlignment="Left" Height="200" VerticalAlignment="Top" Width="160" Margin="10,10,0,0">
<ListView.Resources>
    <Style TargetType="GridViewColumnHeader">
        <Setter Property="Visibility" Value="Collapsed" />
    </Style>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                        <GridViewRowPresenter />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListView.Resources>
<ListView.View>
    <GridView>
        <GridViewColumn Width="105" DisplayMemberBinding="{Binding HandNaam}"/>
        <GridViewColumn Width="45" DisplayMemberBinding="{Binding Betaling}"/>
    </GridView>
</ListView.View>
</ListView>

C#:

List<Hand> hands = new List<Hand>();
//Bet has been changed, (re-)populate the ListView
void Betchanged()
{
    hands.Clear();
    lvTest.ItemsSource = null;
    for (int i = 0; i <= 8; i++)
    {
        hands.Add(new Hand(Hand.hands[i], bet));
    }
    lvTest.ItemsSource = hands;
}

//Game ends
//After checking for a winning hand, highlight that hand in the ListView
private void EndGame()
{
    //Do some stuff

    //Check if there's a winning hand
    int winnings;
    Hand hand = null;
    winnings = Poker.FindWin(splK, hands, out hand); //out hand is of type Hand

    //If there's a winning hand, highlight it in the ListView
    if (hand != null)
    {
        foreach (Hand h in lvTest.Items)
        {
            if (h.HandName == hand.HandName)
            {
                //This seems like the most logical (maybe not most efficient) way to find the correct item in the ListView
                //Here's where the Background property for the ListViewItem should be changed
            }
        }
    }
    //Do some more stuff
}

PS:我的 XAML 中的当前模板样式覆盖了我的 ListViewItem 的 hover/click 交互。

编辑:这是一个屏幕截图,其中包含应更改 ListViewItem 的背景时的可能情况:

为了通过 Binding 通知控件其内容已更改,您的 ItemsSource 需要实施 INotifyCollectionChanged。目前,实现此接口的最常见的泛型集合是 ObservableCollection<T>.

hands 应该是 ObservableCollection<Hand> 而不是 List<Hand>.

根据评论编辑:

WPF Binding 处理更改通知。对于属性,这意味着在需要通知其属性已更改的 class 上实施 INotifyPropertyChanged。您的 Hand class 应该在您要更改的特定值发生更改时实施 INotifyPropertyChanged

表示逻辑应由 View class(或与 View 相关的代码(如 Converter)处理,因此您应该绑定到您的模型 属性 值并使用转换器将其转换为 Brush 对象。

您可以只在模型对象上公开 Brush,但这会破坏 MVVM 模式,因为 ViewModel 不应该具有 View-specific/presentation 技术 classes嵌入其中以便与演示技术无关。

根据第二条评论进行第二次编辑:

转换器是通过实现 IValueConverter 接口 ( MSDN : IValueConverter documentation ) 将值从一种类型转换为另一种类型的代码。它们需要在您的 XAML 中声明为资源,并在 Binding.

中使用 StaticResource 指令进行引用

可以在 WPFTutorial.com - Value Converters

找到有关此内容(以及其他 WPF 基本主题)的优秀教程