Converter Binding for Label

Hi,

I have a label, and I want the label to display different things depending on the bool value returned from a function in my ViewModel.
Let's say the function is called getConnection() - how do I bind to it so that the style will change based on the result?

I'm 99% sure the rest of the code/markup will run, I just need to bind to the return value of the function in my ViewModel. I've marked with ???? where this code needs to go.

<Label.Style>
    <x:Binding ?????????????>
        <Binding.Converter>

            <services:BoolToObjectConverter x:TypeArguments="Style">
                                                        <services:BoolToObjectConverter.TrueObject>
                                                            <Style TargetType="Label">
                                                                <Setter Property="Text" Value="Connected" />
                                                                <Setter Property="TextColor" Value="White" />
                                                            </Style>
                                                        </services:BoolToObjectConverter.TrueObject>

                                                        <services:BoolToObjectConverter.FalseObject>
                                                            <Style TargetType="Label">
                                                                <Setter Property="Text" Value="Not Connected" />
                                                                <Setter Property="TextColor" Value="Gray" />
                                                            </Style>
                                                        </services:BoolToObjectConverter.FalseObject>
            </services:BoolToObjectConverter>

        </Binding.Converter>
    </x:Binding>
</Label.Style>

Thanks!

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    how do I bind to it so that the style will change based on the result?

    No converter.
    DataTrigger

    Here's a Label that changes its text based on IsConnected. Add in more properties for things like color, background, whatever

                                                <Label
                                                    Grid.Row="0"
                                                    Grid.Column="0"  
                                                    HorizontalTextAlignment="Start"
                                                    VerticalTextAlignment="Start">
    <Label.Triggers>
    
                                                                <DataTrigger
                                                                    Binding="{Binding IsConnected}"
                                                                    TargetType="{x:Type Label}"
                                                                    Value="False">
                                                                    <Setter Property="Text" Value="Disconnected" />
                                                                </DataTrigger>
    </Label.Triggers>
                                                    </Label.Style>
                                                </Label>
    
  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    and I want the label to display different things depending on the bool value returned from a function in my ViewModel.

    Sounds very anti-mvvm

    If the function does something that's great. Update the string property the label is binded to. Then let MVVM binding do its job and update the content of the label. But putting a mountain of psuedo-logic behavior in the XAML is just a maintenance mess, long term.

    Things like hte color can be one datatrigger. If connected is true, then textcolor is grey. For example.
    But don't start changing the text in the UI to something different than the text in the ViewModel property you're binding to. That's just dirty as all get out and will really piss off your team mates.

  • DR_BartDR_Bart Member ✭✭

    OK, however what if I need to run a function with a parameter?

    e.g. I have an ObservableCollection and I want to display each item in a listview with a label. The style of the label that each item gets depends on the boolean result of some function, and that function must be passed the respective item from the listview?

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    At some point you are getting the data from somewhere. So when you get the data foreach on the collection, running each element through the method. That gets you a result back to a property on the element.
    Now that your collection is processed, it is the binding for the ListView using the DataTemplate technique described.

  • DR_BartDR_Bart Member ✭✭


    <ListView.ItemTemplate>

                            <ViewCell>
                                <ViewCell.View>
    
                                    <StackLayout Orientation="Horizontal" Padding="5" BackgroundColor="Gray">
    
                                        <Label Text="{Binding Name, Converter={Services:NullToUnnamedDeviceConverter}}" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" FontSize="Medium" TextColor="White" />
    
    
    
                                        <Label FontSize="Medium" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand">
                                            <Label.Style>
    
                                                <x:Binding BOOLEAN FUNCTION THAT CHECKS IF THE CURRENT DEVICE IS THE DEVICE WE ARE CONNECTED TO>
                                                    <Binding.Converter>
    
                                                        <Services:BoolToObjectConverter x:TypeArguments="Style">
                                                            <Services:BoolToObjectConverter.TrueObject>
                                                                <Style TargetType="Label">
                                                                    <Setter Property="Text" Value="Connected" />
                                                                    <Setter Property="TextColor" Value="White" />
                                                                </Style>
                                                            </Services:BoolToObjectConverter.TrueObject>
    
                                                            <Services:BoolToObjectConverter.FalseObject>
                                                                <Style TargetType="Label">
                                                                    <Setter Property="Text" Value="{Binding BondState, Converter={Services:BondedStateToStringConverter}}" />
                                                                    <Setter Property="TextColor" Value="Red" />
                                                                </Style>
                                                            </Services:BoolToObjectConverter.FalseObject>
                                                        </Services:BoolToObjectConverter>
    
                                                    </Binding.Converter>
                                                </x:Binding>
    
                                            </Label.Style>
                                        </Label>
    
    
                                    </StackLayout>
    
                                </ViewCell.View>
                            </ViewCell>
    
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
    

    This is my code. I realise it may not be ideal, however I need to be able to check if I am currently connected to a device, and if not (return value = false), display what the bond state is, This needs to be done for each for each device in the listview. Any advice how I might go about this?

  • DR_BartDR_Bart Member ✭✭

    I used a data template selector in the end. For my case with a listview it made the most sense. Thanks everyone for the advice. Even if I didn't use your solution, I learnt from it!

  • NicolasKrierNicolasKrier FRMember ✭✭✭

    You're welcome :-)

Sign In or Register to comment.