Raymond Ativie
Raymond Ativie

Reputation: 1828

Changing the image of a button in XAML using C#

i recently started learning windows phone 8.1 Development using C#. i have no prior experience to C# or XAML till last week.

I'm trying to change the image in a button as seen below (XAML)

<Button x:Name="playButton"
                    VerticalAlignment="Stretch"
                    Click="Button_Click">
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="controlImg" Source="/Assets/Media-Play.png" />
                    <TextBlock Text=" Play" />
                </StackPanel>
            </Button>

The initial Image is a 'play' icon and a text which says play. This works and renders properly. But i want to change that image when the button is clicked to a 'pause' icon and the text which says Pause.

Here is my C# code so far

    private mediaState medState = mediaState.Stopped;

    public BitmapImage iconStop = new BitmapImage(new Uri("ms-appx:///Assets/Media-Stop.png", UriKind.RelativeOrAbsolute));
    public BitmapImage iconPause = new BitmapImage(new Uri("ms-appx:///Assets/Media-Pause.png", UriKind.RelativeOrAbsolute));
    public BitmapImage iconPlay = new BitmapImage(new Uri("ms-appx:///Assets/Media-Play.png", UriKind.RelativeOrAbsolute));


    private void Button_Click(object sender, RoutedEventArgs e)
    {


        switch (medState)
        {
            case mediaState.Playing:
                medState = mediaState.Paused;
                mediaE.Pause();
                playButton.Content = " Play";
                controlImg.Source = this.iconPlay;
                break;

            case mediaState.Paused:
                medState = mediaState.Playing;
                mediaE.Play();
                playButton.Content = " Pause";
                controlImg.Source = this.iconPause;
                break;

            case mediaState.Stopped:                    
                medState = mediaState.Playing;
                mediaE.Play();
                playButton.Content = " Pause";
                controlImg.Source = this.iconPause;
                break;
            default:
                break;
        }


    }

    public enum mediaState
    {
        Playing,
        Paused,
        Stopped
    }

mediaE is the mediaElement object. Currently when you click the button the text changes but the image in the button doesn't disappears

WHAT I'VE TRIED SO FAR:

i checked the MSDN article for using BitmapImage and some other questions here and the usually say something like this

// Create source
BitmapImage myBitmapImage = new BitmapImage();

// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(@"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water Lilies.jpg");

But my visual studio doesn't even recognise BitmapImage.BeginInit() as a valid function.

i also checked this question: BitmapImage missing BeginInit() and EndInit() function? Where the answer said that the Class wasn't implemented the same way for windows phone. Checking the windows phone documentation (http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.media.imaging.bitmapimage%28v=vs.105%29.aspx) of the class didn't show any clear way of achieving what i wanted.

NOTE: i am developing for windows phone 8.1. please any help would be appreciated. Thanks

Upvotes: 3

Views: 8109

Answers (1)

loop
loop

Reputation: 9242

Things are just behaving weird in Windows phone runtime apps may be it is because we haven't explored it too much. But will do it.

I have tried things using Binding too that is also showing some issues in updating, so what i am proposing is not a good solution but a working one. I will update here a good solution latter when i made that work.

Solution :-

Update your xaml as it is not the right way you should use ContentTemplate for altering display for any control. and check difference between control and content template.

Xaml :-

    <Button x:Name="PlayButton" Grid.Row="1"
                Click="PlayButton_OnClick" >
        <Button.ContentTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="ControlImg" 
                   Stretch="Fill" Width="100"
                   />
                    <TextBlock Text=" Play" />
                </StackPanel>
            </DataTemplate>
        </Button.ContentTemplate>
    </Button>

Change your Button Click event by adding some code :-

 private async void PlayButton_OnClick(object sender, RoutedEventArgs e)
    {
        var btn = sender as Button;
        // For TextBlock change the children collection index to 1
        var img = (Image)(btn.ContentTemplateRoot as StackPanel).Children[0];

        switch (medState)
        {
            case mediaState.Playing:
                medState = mediaState.Paused;
             //   mediaE.Pause();
                PlayButton.Content = " Play";
                img.Source = this.iconPlay;
                break;

            case mediaState.Paused:
                medState = mediaState.Stopped;
               // mediaE.Play();
                PlayButton.Content = " Pause";
                img.Source = this.iconPause;
                break;

            case mediaState.Stopped:
                medState = mediaState.Playing;
               // mediaE.Play();
                PlayButton.Content = " Stop";
                img.Source = this.iconStop;
                break;
            default:
                break;
        }
    }

For Windows phone SilverLight I haven't remove this info as it is useful.

Here I used the Windows phone 8.1 Silverlight app template

You can check the ImageFailed EventHandler ExceptionRoutedEventArgs e parameter then you will see "AG_E_NETWORK_ERROR" that is related to cross-scheme security problem in Silverlight. you can google AG_E_NETWORK_ERROR then you will get lot's of stuff related to it.

Solution Code :-

Change images

public BitmapImage iconStop = new BitmapImage();
public BitmapImage iconPause = new BitmapImage();
public BitmapImage iconPlay = new BitmapImage();

private void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
    switch (medState)
    {
        case mediaState.Playing:
            medState = mediaState.Paused;
            //  mediaE.Pause();
            playButton.Content = " Play";

            var sri = Application.GetResourceStream(new Uri("Assets/download(1).jpg", UriKind.Relative));
            iconStop.SetSource(sri.Stream);
            ControlImg.Source = iconStop;
            break;

        case mediaState.Paused:
            medState = mediaState.Stopped;
            //  mediaE.Play();
            playButton.Content = " Pause";
            var sri1 = Application.GetResourceStream(new Uri("Assets/download(2).jpg", UriKind.Relative));
            iconPlay.SetSource(sri1.Stream);
            ControlImg.Source = iconPlay;
            break;

        case mediaState.Stopped:
            medState = mediaState.Playing;
            // mediaE.Play();
            playButton.Content = " stopped";
            var sri2 = Application.GetResourceStream(new Uri("Assets/download(1).jpg", UriKind.Relative));
            iconStop.SetSource(sri2.Stream);
            ControlImg.Source = iconStop;
            break;
        default:
            break;
    }

Hope it will help you.

Upvotes: 2

Related Questions