Setting DataContext of an “Image” element inside button Click

I am very new to the data binding concept so excuse my question if it appears silly to you. This project is to learn some API functionality and WPF Data Binding along with it. But here is what problem I face when I try to show an icon on screen by setting Data Context of an Image element in WPF to property from a Class that stores the Path of the image used for displaying on screen. I have the following Image:

<Image x:Name="imgWeatherIcon" Grid.Column="2" HorizontalAlignment="Left" Margin="380,134,0,0" VerticalAlignment="Top"
           Width="90" Height="90" Source="{Binding ImgPath, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, diag:PresentationTraceSources.TraceLevel=High}">
        <Image.DataContext>
            <c:ConditionsNow/>
        </Image.DataContext>
    </Image>

I bind the Source to a property so whenever this property changes I get the new icon/image displaying on screen. The problem is that this only works if DataContext is set on start of the program (Main Window) and I need it to be se inside a button click

Here is the code that works:

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        ApiHelper.InitializeApiClient();

        ConditionsNow conditionsObject = new();
        imgWeatherIcon.DataContext = conditionsObject;
        conditionsObject.ImgPath = @"https://developer.accuweather.com/sites/default/files/01-s.png";

    }

Note that ‘imgWeatherIcon’ is a Label where I display the icon/image and I am setting it’s DataContext to the property ‘ImgPath’. This is just to clarify the “imgWeatherIcon” since didn’t include WPF code for it, but I can do if necessary.

If I do this every time I start up the application the datacontext is set properly to the ImgPath property and is updated in the UI.

But here is where I need it to work and can’t figure out why doesn’t it work:

    public ConditionsNow condObject = new();

    private async void BtnCity_Click(object sender, RoutedEventArgs e)
    {
        imgWeatherIcon.DataContext = condObject;
        condObject.ImgPath = @"G:Visual StudioProjectsTestingAccuWeatherAppaccuweather-icon.jpg";
                    
    }

I know I lack knowledge of databinding and WPF, but would appreciate if someone give me a hint where the problem is. I did a lot of research about binding etc. but still can’t figure this out. Btw if this is helpful for property ‘ImgPath’ I have INotifyPropertyChanged implemented to be able to track changes.

Answer

You should not change the whole DataContext binding. You set the DataContext only once, and then only change the underlying properties that are bound to the UI. In your case, you should only change the ImgPath property. Therefore, remove the following from the button click event:

imgWeatherIcon.DataContext = condObject;

Make sure that ConditionsNow implement the INotifyPropertyChanged interface, so that you can call OnPropertyChanged() when changing the value of ImgPath. This is to ensure that the binding will cause the UI to change its presentation.

So your ConditionsNow class should have a form similar to the below:

public class ConditionsNow
{    
    private string _imgPath;
    public string ImgPath
    {
        get => _imgPath;
        set
        {
            _imgPath = value;
            OnPropertyChanged();
        }
    }
}