Как установить свойство WPF DataGrid (mvvm) в событии «MouseDown» на основе «sender»?

#c# #wpf #datagrid #onmousedown

#c# #wpf #datagrid #onmousedown

Вопрос:

У меня возникли некоторые проблемы с установкой значения одного свойства (события MouseDown) на основе его отправителя. У меня есть «MyPhotoA» и «MyPhotoB», привязанные к ObservableCollection. Оба запускают одно и то же событие «MyOnClick», вот xaml:

 ... stuff
<DataTemplate>
  <Image Source="{Binding MyPhotoA, UpdateSourceTrigger=LostFocus}" MouseDown="MyOnClick" />
</DataTemplate>
... stuff
<DataTemplate>
  <Image Source="{Binding MyPhotoB, UpdateSourceTrigger=LostFocus}" MouseDown="MyOnClick" />
</DataTemplate>
... stuff
  

Эти две datatemplates используются для двух datagridtemplatecolumns в datagrid. Следовательно, есть два столбца изображений, и пользователь нажимает на один. Я хочу установить источник на нажатом изображении.

Событие «MyOnClick» выглядит примерно так:

 private void MyOnClick(object sender, MouseButtonEventArgs e)
{
  var myImage File.ReadAllBytes("c:\MyImage.jpeg")
  var dc = (sender as System.Windows.Controls.Image).DataContext;
  MyModelClass itemSelected = (MyModelClass)dc;
  itemSelected.PhotoA = myImage;//Setting PhotoA
  itemSelected.PhotoB = myImage;//Setting PhotoB
  //How to set the photo based on "sender" property? Like:
  //sender.[somestuff]=myImage;
}
  

Я хотел бы использовать тот же метод для установки данных в PhotoA и PhotoB на основе привязанного к нему свойства sender. Таким образом, если пользователь щелкает в ячейке DataGrid «PhotoA», изображению присваивается значение «PhotoA». Если щелчок выполнен в «PhotoB», то устанавливаются данные «PhotoB».
!!!Примечание!!!: Я не хочу таких трюков, как

 If (sender.name="PhotoA") then
  itemSelected.PhotoA = myImage;
else
  itemSelected.PhotoB = myImage;
  

Заранее спасибо

[Обновление обходного пути]

Я не смог найти ответ, поэтому я использовал обходной путь: 1) отредактируйте код xaml, добавив свойство «name» к каждой фотографии:

 <DataGridTemplateColumn>
  <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <Image Name="ImageMyPhotoA" Source="{Binding Photo}" MouseDown="MyOnClick" />
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
  

При событии я вручную добавил ячейку в наблюдаемую коллекцию.

 private void MyOnClick(object sender, MouseButtonEventArgs e)
{        
 var myImage = File.ReadAllBytes("c:\MyImage.jpeg");
 var dc = (sender as Image).DataContext;
 MyModelClass itemSelected = (MyModelClass)dc;
 var senderName = (sender as Image).Name;
 if (senderName == "ImagePhotoA")
 {
     itemSelected.PhotoA = myImage;
 }
 if (senderName == "ImagePhotoB")
 {
   itemSelected.PhotoB = myImage;
 }
}
  

Заключение
Настройка свойств в событии «MouseDown» на основе отправителя (Sender.[SomeSenderProperty] = «Что-то») кажется невозможным ИЛИ чрезмерно сложным. Я предлагаю отметить имя отправителя в xaml (как в примере). Спасибо добрым ребятам за вашу помощь, я действительно ценю.

Комментарии:

1. Просто используйте 2 разных обработчика событий.

2. UpdateSourceTrigger=LostFocus привязки к источнику изображения совершенно бессмысленны, это вообще не влияет. Также «У меня есть «MyPhotoA» и «MyPhotoB», привязанные к ObservableCollection» , не имеет смысла. Что именно должен делать этот код? Вы даже не говорите нам, что такое PhotoA и PhotoB.

3. @Freddy Предполагая, что моя интерпретация верна. Я думаю, могло бы быть понятнее, что две таблички datatemplate используются в двух столбцах datatemplate в datagrid. Я отредактирую вопрос, но, пожалуйста, подумайте, можете ли вы сами улучшить ясность.

Ответ №1:

По сути, вы пытаетесь установить свойство источника изображения, на которое нажал пользователь.

Когда вы делаете это, вы, по-видимому, хотите, чтобы оно сохранялось, и вы, вероятно, не захотите перезаписывать привязку, поэтому сделайте вашу привязку двухполосной.

 <Image Source="{Binding MyPhotoA, Mode=TwoWay}"
  

В вашем обработчике кликов.

Приведите вашего отправителя к изображению.

 var img = sender as Image;
  

(Вы должны регулярно проверять значение null, когда делаете что-либо еще.)

Но это дает вам ссылку на соответствующий элемент управления изображением для работы.

Установите значение.

Как указывает Клеменс, я слишком усложнял это с:

  img.SetCurrentValue(SourceProperty, Abitmapimage);
  

И вы можете просто сделать:

  img.Source = new BitmapImage(new Uri(@"C:MyImage.jpeg"));
  

Комментарии:

1. Вы могли бы просто написать img.Source = new BitmapImage(new Uri(@"C:MyImage.jpeg")); . Нет необходимости в SetCurrentValue, BeginInit или EndInit. Для SetCurrentValue двухполосная привязка не заменяется, когда целевому свойству присваивается значение.

2. Большое спасибо за ваше время. Извините, не сработало. Я изменил «img. Источник», и изображение в сетке отобразило изменение, как ожидалось. Но модель не отразила изменение. Это означает, что когда я меняю изображение, а затем нажимаю кнопку «Сохранить» (я опустил ее), класс сохранения, привязанный к наблюдаемой коллекции, имеет старое изображение.

3. Вы изменили режим привязки на twoway? Как выглядит row viewmodel?

4. Привет @Andy. Я действительно ценю ваши усилия, пытающиеся мне помочь, вы, несомненно, хороший парень. Я попробовал режим «twoway», но, как ни странно, изображение не отображалось, когда я его включал.

5. Спасибо. Я пытаюсь помогать людям. Я думаю, нам нужно увидеть больше кода. В частности, какой бы ни была ваша модель просмотра строк. Тогда я мог бы попробовать какое-то воспроизведение.