2

I have an application with 3 comunicationstates: Connected, Disconnected and Pending. The communication state are controled by some other paramers. I want to display the corresponding image on the screen controlled by an IValueConverter. But I cant get it to work.

Heres is my Xaml code for includeing the 3 images :

<Image x:Name="connectedImage"  
    Visibility="{Binding ConnectionWithServerEstablished, Converter={StaticResource communitationStateToVisibilityConverter}, ConverterParameter=ConverterParameterConnected}"
    Source="Assets/connected.png"
    Stretch="None"
    HorizontalAlignment="Center" />



<Image x:Name="disconnectedImage"
    Visibility="{Binding ConnectionWithServerEstablished, Converter={StaticResource communitationStateToVisibilityConverter}, ConverterParameter=ConverterParameterDisconnected}"
    Source="Assets/disconnect.png"
    Stretch="None"
    HorizontalAlignment="Center" />


<Image x:Name="pendingImage"
    Visibility="{Binding ConnectionWithServerEstablished, Converter={StaticResource communitationStateToVisibilityConverter}, ConverterParameter=ConverterParameterPending}"
    Source="Assets/pending.png"
    Stretch="None"
    HorizontalAlignment="Center" />

Here is the methos controlling CommunitationState

public enum CommunitationState { Connected, Disconnected, Pending }

public CommunitationState ConnectionWithServerEstablished
{
    get
    {
        if (IRCommandSent)
            return CommunitationState.Disconnected;

        if (wifiConnected && !fcConnected)
            return CommunitationState.Pending;

        return wifiConnected ? CommunitationState.Connected : CommunitationState.Disconnected;
    }
}

And last but not least the converter:

  public class CommunitationStateToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var result = Visibility.Collapsed;

            if ((string)parameter == "ConverterParameterConnected")
                result = (CommunitationState)value == CommunitationState.Connected ? Visibility.Visible : Visibility.Collapsed;

            if ((string)parameter == "ConverterParameterDisconnected")
                result = (CommunitationState)value == CommunitationState.Disconnected ? Visibility.Visible : Visibility.Collapsed;

            if ((string)parameter == "ConverterParameterPending")
                result = (CommunitationState)value == CommunitationState.Pending ? Visibility.Visible : Visibility.Collapsed;
            Debug.WriteLine("value={0}, parameter={1}, result={2}", value,   (string)parameter, result);
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

The Databinding works like its supposed to do. I know that for sure bacause I have a textbox bound an other method displaying the state as text. My converter gets called, I know that for sure because I can place a break point in it.

So there is something wrong with my converter, because I allways ends up with a collapsed image.

**** EDIT ****

Here are some output from my debug.Writeline

I startup Connected:

value=Connected, parameter=ConverterParameterConnected, result=Visible
value=Connected, parameter=ConverterParameterDisconnected, result=Collapsed
value=Connected, parameter=ConverterParameterPending, result=Collapsed

I change to pending:

value=Pending, parameter=ConverterParameterConnected, result=Collapsed
value=Pending, parameter=ConverterParameterDisconnected, result=Collapsed
value=Pending, parameter=ConverterParameterPending, result=Visible

I startup pending:

value=Connected, parameter=ConverterParameterConnected, result=Visible
value=Connected, parameter=ConverterParameterDisconnected, result=Collapsed
value=Connected, parameter=ConverterParameterPending, result=Collapsed
value=Pending, parameter=ConverterParameterConnected, result=Collapsed
value=Pending, parameter=ConverterParameterDisconnected, result=Collapsed
value=Pending, parameter=ConverterParameterPending, result=Visible

This is correct because my program defaults to connected, and after a second it realizes that it can not see the TCP server but still have acces to Wifi so i changes state to pending.

Jens Borrisholt
  • 6,174
  • 1
  • 33
  • 67
  • If you put Visibility=Visible in the XAML instead of the binding, do the images show? Also, try to step through your value converter with the debugger. – helb Nov 14 '14 at 07:13
  • I havent tried that, Bu I have tried to hardcode the converter to return Visibility.Visible and then the images are shown. – Jens Borrisholt Nov 14 '14 at 07:14
  • What values of parameter does the debugger show inside Convert()? – helb Nov 14 '14 at 07:15
  • The program starts up and defaults to Connected. Then the state changes to pending (wich is correct) and this is what I get in the debugger: value=Connected parameter=ConverterParameterConnected value=Pending parameter=ConverterParameterDisconnected value=Pending parameter=ConverterParameterPending value=Pending parameter=ConverterParameterConnected – Jens Borrisholt Nov 14 '14 at 07:21
  • And yes I've just testes, that I can show the images by hardcodeing the value in the XAML file – Jens Borrisholt Nov 14 '14 at 07:24
  • You *are* firing the PropertyChangedEvent when the `ConnectionWithServerEstablished` property changed, right? – helb Nov 14 '14 at 07:34
  • Yes. Called from a property public bool FCConnected { get { return fcConnected; } set { if (this.fcConnected != value) { this.fcConnected = value; ... this.OnPropertyChanged("ConnectionWithServerEstablished"); this.OnPropertyChanged("ConnectionWithServerLabel"); } } } – Jens Borrisholt Nov 14 '14 at 07:42
  • I don't see anything wrong with your ValueConverter, Binding and XAML. There must be something else here. In most cases, property change notification is off. – helb Nov 14 '14 at 07:51
  • 2
    The code works ok as Ive pulled it into a test app with TextBlocks instead of your images. As helb says the likely cause is that you are not calling OnPropertyChanged("ConnectionWithServerEstablished") in the correct place ie when any affected properties change or that the images just dont appear for some reason with Visibility="Visible". The Converter is not the problem – SWilko Nov 14 '14 at 11:56
  • You where right! OnPropertyChanged Didn't get called. I've located the bug else where. So thank you for your time. – Jens Borrisholt Nov 14 '14 at 12:27

1 Answers1

1

From your comments, it is most likely that your ConnectionWithServerEstablished property does not change to make the images visible and/or you do not fire a PropertyChanged event when the property value changed.

You can do this for example by firing the event in the setter of your dependent properties:

public bool IRCommandSent
{
    set
    {
        // set the value
        // ...

        // notify event listeneers that the ConnectionWithServerEstablished may have changed
        if (PropertyChanged != null)
        {
             PropertyChanged(this, new PropertyChangedEventArgs("ConnectionWithServerEstablished"));
        }
    }
}

The class you use as DataContext (your ViewModel) must of course implement INotifyPropertyChanged for that.

helb
  • 7,609
  • 8
  • 36
  • 58
  • As you can see on my lates comment that is not the case. – Jens Borrisholt Nov 14 '14 at 07:43
  • Code for OnPropertyChanged: protected void OnPropertyChanged(string name) { var handler = this.PropertyChanged; if (handler != null && this.dispatcher != null) { dispatcher.BeginInvoke(() => { handler(this, new PropertyChangedEventArgs(name)); }); } } – Jens Borrisholt Nov 14 '14 at 07:44