Как я могу изменить изображение в Listview во время выполнения в WPF? - PullRequest
0 голосов
/ 26 марта 2020

Я хотел бы изменить изображение в ячейке, когда пользователь нажимает на изображение. Исходное изображение - «стрелка вправо», и когда пользователь нажимает «стрелку вправо», оно должно быть «красный х», но значок не меняется. Значение свойства (Binding value [3]) меняется каждый раз на 0 и 1, поэтому оно работает нормально.

Вот мой код:

<GridViewColumn  Header="Functions">
                                    <GridViewColumn.CellTemplate>
                                        <DataTemplate>
                                            <StackPanel Orientation="Horizontal">
                                                <Image x:Name="MoveImg"  Cursor="Hand" ToolTip="Move Losses" MaxWidth="20" MaxHeight="20" Margin="3,3,3,3" MouseLeftButtonUp="MoveImg_MouseLeftButtonUp" >
                                                    <Image.Style>
                                                        <Style TargetType="{x:Type Image}">
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding Value[3]}" Value="1">
                                                                    <Setter Property="Source" Value="pack://application:,,,/Resources/x.ico"/>
                                                                </DataTrigger>
                                                                <DataTrigger Binding="{Binding Value[3]}" Value="0">
                                                                    <Setter Property="Source" Value="pack://application:,,,/Resources/right_arrow.png"/>
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </Image.Style>
                                                </Image>
                                            </StackPanel>
                                        </DataTemplate>
                                    </GridViewColumn.CellTemplate>
                                </GridViewColumn>

И код в DtListView.xaml .cs

Dictionary<string, double[]> prDict = new Dictionary<string, double[]>();
Dictionary<string, string[]> lossTransferDict = new Dictionary<string, string[]>();
public Dictionary<string, double[]> PrDict { get => prDict; set => prDict = value; }

 public DtListView()
        {
            InitializeComponent();
        }


 private void MoveImg_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {



            if (TopLossesLv.SelectedItems != null)
            {
                foreach (KeyValuePair<string, double[]> item in TopLossesLv.SelectedItems)
                {
                    if (!lossTransferDict.ContainsKey(item.Key))
                    {
                        lossTransferDict.Add(item.Key, new string[4] { line, item.Value[0].ToString(), item.Value[1].ToString(), item.Value[2].ToString()});
                        prDict[item.Key][3] = 1; // Modify Value for Picture change

                    }
                    else
                    {
                        lossTransferDict.Remove(item.Key);
                        prDict[item.Key][3] = 0; // Modify Value for Picture change

                    }


                }
            }

        }

1 Ответ

0 голосов
/ 27 марта 2020

Это не C. Это C#. C# является объектно-ориентированным. Привязка к массиву связанных значений не является хорошей идеей по многим причинам. Вместо этого связывайте с объектом, который инкапсулирует связанные значения массива.

Вместо привязки к словарю массивов, вы должны привязать к коллекции объектов. Для этого вам необходимо преобразовать массив в класс, который реализует INotifyPropertyChanged.
Каждое поле массива становится свойством класса. Вы должны применить этот рефакторинг ко всем вашим Binding.Source, где источником является массив значений. В конце вы сможете привязать только к спискам.

Избегайте привязывания элементов управления к словарям или массивам.

Это простой пример использования объектов (моделей данных) для заполнения ListView и изменения содержимого ячейки GridView (Image) на основе значения свойства SimpleDataObject.IsActive модели данных SimpleDataObject:

SimpleDataObject.cs

class SimpleDataObject : INotifyPropertyChaged
{ 
  // Constructor
  public SimpleDataObject(string data) => this.DataValue = data;

  private bool isActive;
  public bool IsActive
  {
    get => this.isActive;
    set
    {
      this.isActive = value;
      OnPropertyChanged();
    }
  }   

  private string dataValue;
  public string DataValue
  {
    get => this.dataValue;
    set
    {
      this.dataValue = value;
      OnPropertyChanged();
    }
  }   

  #region INotifyPropertyChanged implementation

  public event PropertyChangedEventHandler PropertyChanged;
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }

  #endregion
}

ViewModel. cs

// Binding source
class ViewModel : INotifyPropertyChaged
{ 
  public ViewModel()
  {
    this.SimpleDataObjects = new ObservableCollection<SimpleDataObject>() 
    {
      new SimpleDataObject("Data value 1"),
      new SimpleDataObject("Data value 2"),
      new SimpleDataObject("Data value 3")
    }
  }

  public ObservableCollection<SimpleDataObject> SimpleDataObjects { get; set; }
}

MainWindow.xaml.cs

partial class MainWindow : Window
{
  private void OnImageMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
  {
    var image = sender as Image;
    var dataItem = image.DataContext as SimpleDataObject;
    dataItem.IsActive = true; // Toggle image
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <ViewModel />
  </Window.DataContext>

  <ListView ItemsSource="{Binding SimpleDataObjects}">
    <ListView.View>
      <GridView>
        <GridView.Columns>
          <GridViewColumn  Header="Functions">
            <GridViewColumn.CellTemplate>
              <DataTemplate DataType="{x:Type SimpleDataObject}">
                <StackPanel Orientation="Horizontal">
                  <TextBlock Text="{Binding DataValue}"/>

                  <Image MouseLeftButtonUp="OnImageMouseLeftButtonUp">
                    <Image.Style>
                      <Style TargetType="Image">

                        <!-- Default value. Applies when the observed property IsActive returns false -->
                        <Setter Property="Source" Value="pack://application:,,,/Resources/right_arrow.png" />

                        <Style.Triggers>
                          <DataTrigger Binding="{Binding IsActive}" Value="True">
                            <Setter Property="Source" Value="pack://application:,,,/Resources/x.ico" />
                          </DataTrigger>
                        </Style.Triggers>
                      </Style>
                    </Image.Style>
                  </Image>
                </StackPanel>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView.Columns>
      </GridView>
    </ListView.View>
  </ListView>
</Window>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...