-1

I'm having some trouble to set one property (MouseDown event) value based on it's sender. I have "MyPhotoA" and "MyPhotoB" binded to an observableCollection. Both trigger the same event "MyOnClick" Here is the xaml:

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

These two datatemplates are used for two datagridtemplatecolumns in the datagrid. Hence there are two columns of images and the user clicks one. I want to set the source on the image clicked.

The event "MyOnClick" is something like this:

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;
}

I'd like to use the same method to set data in PhotoA and PhotoB based on the sender property binded to it. So if user click in the "PhotoA" DataGrid cell, the image is setted to "PhotoA". If click is done in "PhotoB" then "PhotoB" data is setted. !!!Note!!!: I don't want tricks like

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

Thanks in advance

[Workaround Update]

I could not find the answer so I used a workaround: 1)edit xaml code, adding a property "name" to each Photo:

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

On the event, I manually added the bin to the the observable collection.

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;
 }
}

Conclusion Setting properties in "MouseDown" event based on Sender (Sender.[SomeSenderProperty] = "Something") seems not possible OR over complicated. I suggest to mark the sender's name in xaml (like the example). Thanks for the good fellows for your help, I really appreciate.

Freddy
  • 75
  • 7
  • Simply use 2 different event handlers. – Sinatr Aug 20 '20 at 07:37
  • 1
    `UpdateSourceTrigger=LostFocus` on the Image Source Bindings is totally pointless, It has no effect at all. Also *"I have "MyPhotoA" and "MyPhotoB" binded to an observableCollection"* does not make sense. What exactly is this code supposed to do? You don't even tell us what PhotoA and PhotoB are. – Clemens Aug 20 '20 at 07:42
  • @Freddy Assuming my interpretation is correct. I think it could be clearer that the two datatemplates are used in two datatemplate columns in a datagrid. I'll edit the question but please consider whether you can improve clarity yourself. – Andy Aug 20 '20 at 09:03

1 Answers1

0

You're essentially trying to set the source property of an image the user clicked.

When you do that you want it to persist, presumably, and you probably won't want to overwrite the binding so make your binding twoway.

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

In your click handler.

Cast your sender to image.

var img = sender as Image;

(You should routinely null check when you do as anything.)

But this gives you a reference to the appropriate image control to work with.

Set the value.

As Clemens points out, I was overcomplicating this with:

 img.SetCurrentValue(SourceProperty, Abitmapimage);

And you can just do:

 img.Source = new BitmapImage(new Uri(@"C:\MyImage.jpeg"));
Andy
  • 11,864
  • 2
  • 17
  • 20
  • 1
    You could simply write `img.Source = new BitmapImage(new Uri(@"C:\MyImage.jpeg"));`. No need for SetCurrentValue, BeginInit or EndInit. For SetCurrentValue, a TwoWay Binding is not replaced when a value is assigned to the target property. – Clemens Aug 20 '20 at 08:45
  • Thanks kindly for your time. Sorry, did not worked. I changed "img.Source", and the image in grid displayed the change as expected. But the model did't reflected the change. That means when I change the image and then click my "Save Button" (I omitted it) the save class binded to the observable collection have the old image. – Freddy Aug 20 '20 at 09:33
  • Did you change the binding mode to twoway? What's the row viewmodel look like? – Andy Aug 20 '20 at 09:36
  • Hi @Andy. I really appreciate your effort trying to help me, you are sure a nice fellow. I tried the "twoway" mode, but, strangely the image was not displayed when I include it. – Freddy Aug 20 '20 at 10:19
  • Thanks. I try and help people. I think we need to see more code. Particularly whatever your row viewmodel is. Then i could try for some sort of a reproduction. – Andy Aug 20 '20 at 10:25
  • @Freddy in particular. Check the type of the MyPhotoA and MyPhotoB properties in your row viewmodel. If they are not bitmapimage then when the bound property is set and the data transferred, that could well fail. Square peg, round hole. – Andy Aug 20 '20 at 10:42
  • @Andy Hi Andy. The property is declared as public "byte[] PhotoA" and, by design, I cannot change. My idea was create one unique event for multiple images. But after spending a lot of time, I decided to add "name="MyPhotoA"" to the control, and in the event set the property manually (something I tried to avoid). I really appreciate your time spent. – Freddy Aug 20 '20 at 12:05