Как связать фоновый цвет элементов списка WPF? - PullRequest
0 голосов
/ 28 мая 2018

Я новичок в WPF, и я прочитал много подобных вопросов в Интернете, но я все еще не получаю свою работу по просмотру списка.Я хочу изменить цвет фона элемента представления списка в зависимости от свойства (красного, желтого или зеленого)

itemsSource моего ListView - это наблюдаемый список этого класса:

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 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.Resources, но я также не добился успеха в других подходах.

Ответы [ 3 ]

0 голосов
/ 28 мая 2018

Если вы переместите триггер Style с ListView.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;
              }               
          }
      }
  }

Обратите внимание, что Status и Color теперь имеют оба значения get и set методы доступа и то, что 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.

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>
0 голосов
/ 29 мая 2018

Ваш стиль 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>
0 голосов
/ 28 мая 2018

привязать фон к свойству 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;
               }
           }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...