如何绑定WPF listview项目的backgroundcolor?

时间:2018-05-28 16:29:23

标签: c# wpf

我是WPF的新手,我在网上看过很多类似的问题,但我仍然没有得到listview的工作。我想根据属性(红色,黄色或绿色)更改列表视图元素的背景颜色

我的ListView的itemsSource是此类的可观察列表:

public class ConnectionItem 
{
    public ConnectionItem(string name)
    {
        Name = name;
    }

    public string Name { get; }
    private string _color = "Red";
    public string Color { get => _color; }
    private ConnectionStatus _status;
    public ConnectionStatus Status
    {
        set
        {
            if (value == _status)
            {
                return;
            }
            else
            {
                switch (value)
                {
                    case ConnectionStatus.Connected:
                        _color = "Yellow";
                        break;
                    case ConnectionStatus.Ready:
                        _color = "Green";
                        break;
                    default:
                        _color = "Red";
                        break;
                }
            }
        }
    }
}

我已经在xaml中定义了我的listview,如下所示:

<ListView x:Name="lvConnections">
            <ListView.ItemContainerStyle>
                <Style TargetType="{x:Type ListViewItem}">
                    <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.Resources>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Color}" Value="Green">
                            <Setter Property="Background" Value="Green"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Color}" Value="Red">
                            <Setter Property="Background" Value="Red"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Color}" Value="Yellow">
                            <Setter Property="Background" Value="Yellow"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.Resources>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <StackPanel  Width="150" MaxHeight="50" Grid.Column="0" Grid.Row="0" Orientation="Horizontal" >
                            <TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontWeight="ExtraBlack" TextWrapping="Wrap" Padding="10"/>
                        </StackPanel>
                    </Grid>

                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

绑定不起作用,我的listview元素都没有背景颜色。我不需要通过ListView.Resources绑定完全相同的解决方案,但我也没有在其他方法中取得成功。

3 个答案:

答案 0 :(得分:1)

将背景绑定到Color属性。

<ListView x:Name="lvConnections">
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick" />
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.Resources>
            <Style TargetType="ListViewItem">
               <Setter Property="Background" Value="{Binding Color}"/>
            </Style>
        </ListView.Resources>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <StackPanel  Width="150" MaxHeight="50" Grid.Column="0" Grid.Row="0" Orientation="Horizontal" >
                        <TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontWeight="ExtraBlack" TextWrapping="Wrap" Padding="10"/>
                    </StackPanel>
                </Grid>

            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

并将Color属性设置为画笔对象

public class ConnectionItem 
{
    public ConnectionItem(string name)
    {
        Name = name;
    }

    public string Name { get; }
    private Brush _color = Brushes.Red;
    public Brush Color { get => _color; }
    private ConnectionStatus _status;
    public ConnectionStatus Status
    {
        set
        {
            if (value == _status)
            {
                return;
            }
            else
            {
                switch (value)
                {
                    case ConnectionStatus.Connected:
                        _color = Brushes.Yellow;
                        break;
                    case ConnectionStatus.Ready:
                        _color = Brushes.Green;
                        break;
                    default:
                        _color = Brushes.Red;
                        break;
               }
           }
        }
    }
}

答案 1 :(得分:1)

如果您将触发器StyleListView.Resources移至StackPanel.Resources(并将TargetType更改为StackPanel),则会使用此方法显示背景颜色

<StackPanel  Width="150" MaxHeight="50" Grid.Column="0" Grid.Row="0" Orientation="Horizontal">
    <StackPanel.Resources>
        <Style TargetType="StackPanel">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Color}" Value="Green">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Color}" Value="Red">
                    <Setter Property="Background" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Color}" Value="Yellow">
                    <Setter Property="Background" Value="Yellow"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Resources>
    <TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontWeight="ExtraBlack" TextWrapping="Wrap" Padding="10"/>
</StackPanel>

您还需要在INotifyPropertyChanged上查看实施ConnectionItem,了解更改Status时要更新的颜色。

public class ConnectionItem : INotifyPropertyChanged
  {
      public event PropertyChangedEventHandler PropertyChanged;

      public ConnectionItem(string name)
      {
          Name = name;
      }

      public string Name { get; }

      private string _color = "Red";
      public string Color
      {
          get => _color;
          set
          {
              if (value == _color) return;
              _color = value;
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
          }
      }

      private ConnectionStatus _status;
      public ConnectionStatus Status
      {
          get => _status;
          set
          {
              if (value == _status) return;
              _status = value;
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Status"));
              switch (value)
              {
                  case ConnectionStatus.Connected:
                      Color = "Yellow";
                      break;
                  case ConnectionStatus.Ready:
                      Color = "Green";
                      break;
                  default:
                      Color = "Red";
                      break;
              }               
          }
      }
  }

请注意,StatusColor现在同时拥有getset个访问者 Status设置Color属性而不是直接设置_color字段。

  public partial class MainWindow : Window
  {
      public MainWindow()
      {
          InitializeComponent();

          lvConnections.ItemsSource = new ObservableCollection<ConnectionItem>()
          {
              new ConnectionItem("Starts Connected") { Status = ConnectionStatus.Connected, },
              new ConnectionItem("Starts Ready") { Status = ConnectionStatus.Ready, },
              new ConnectionItem("Starts Default"),
          };
      }

      private void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
      {
          var item = (sender as ListViewItem)?.DataContext as ConnectionItem;
          switch (item.Status)
          {
              case ConnectionStatus.Connected:
                  item.Status = ConnectionStatus.Ready;
                  break;
              case ConnectionStatus.Ready:
                  item.Status = ConnectionStatus.Disconnected;
                  break;
              default:
                  item.Status = ConnectionStatus.Connected;
                  break;
          }
      }
  }

您甚至可以更进一步,完全从Color删除ConnectionItem属性(并在Status中设置切换)并在Status中使用Style值{1}}触发器。

<强> ConnectionItem

public class ConnectionItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ConnectionItem(string name)
    {
        Name = name;
    }

    public string Name { get; }

    private ConnectionStatus _status;
    public ConnectionStatus Status
    {
        get => _status;
        set
        {
            if (value == _status) return;
            _status = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Status"));
        }
    }
}

<强>风格

  <Style TargetType="StackPanel">
      <Style.Triggers>
          <DataTrigger Binding="{Binding Status}" Value="Ready">
              <Setter Property="Background" Value="Green"/>
          </DataTrigger>
          <DataTrigger Binding="{Binding Status}" Value="Disconnected">
              <Setter Property="Background" Value="Red"/>
          </DataTrigger>
          <DataTrigger Binding="{Binding Status}" Value="Connected">
              <Setter Property="Background" Value="Yellow"/>
          </DataTrigger>
      </Style.Triggers>
  </Style>

答案 2 :(得分:0)

您的ListViewItem样式未应用,因为您已将ItemContainerStyle属性设置为另一个Style。您应该将触发器移动到ItemContainerStyle

<ListView x:Name="lvConnections">
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Color}" Value="Green">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Color}" Value="Red">
                    <Setter Property="Background" Value="Red"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Color}" Value="Yellow">
                    <Setter Property="Background" Value="Yellow"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <StackPanel  Width="150" MaxHeight="50" Grid.Column="0" Grid.Row="0" Orientation="Horizontal" >
                    <TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontWeight="ExtraBlack" TextWrapping="Wrap" Padding="10"/>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>