How to change a variable generated by JSON in c#

151 Views Asked by At

I'm having issues with something that should be very easy. I'm creating a flood warning app for windows phone 8. I have an integer Severity, which can be anything from 1 to 4, pulled from a JSON feed. I simply want to change the int to a string corresponding to the severity, then use the strings to populate a text block via binding. Here's the code

namespace FloodAlertsApp
{


public class RootObject
{

    public int Severity { get; set; }
    public string AreaDescription { get; set; }
    public string Raised { get; set; }
    public string severityTxt;      

    public string getsevText()
    {

        switch (Severity)
        {
            case 1:
                severityTxt = "Severe";
                break;
            case 2:
                severityTxt = "Warning";
                break;
            case 3:
                severityTxt = "Alert";
                break;
            case 4:
                severityTxt = "";
                break;
        }
        return severityTxt;
    }
}

And then the xaml where i'm using the binding is as follows,

<phone:PhoneApplicationPage
x:Class="FloodAlertsApp.ListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <!--<RowDefinition Height="Auto"/>-->
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Width="Auto" HorizontalAlignment="Center"   Margin="10,10,10,10">
        <Image Width="Auto" Source="/nrw_logo_linear.png" Stretch="Fill"/>
    </StackPanel>

    <!--ContentPanel - place additional content here-->
    <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">

        <ListBox Name="listBoxBeaches" SelectionChanged="listBoxBeaches_SelectionChanged" Margin="10,10,10,0" Padding="0,0,0,100" Height="{Binding ElementName=ContentPanel, Path=ActualHeight}">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Grid.Row="0" x:Name="TemplateLayout" Margin="0,5,0,5">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="60" />
                        </Grid.ColumnDefinitions>

                        <StackPanel Grid.Row="0" Grid.Column="0" x:Name="Stackpnl">
                            <TextBlock Foreground="Black" FontSize="28" Margin="5,0,5,0" Text="{Binding Path=AreaDescription}"></TextBlock>
Here be the binding---->    <TextBlock Foreground="Black" FontSize="28" Margin="5,0,5,0" Text="{Binding Path=SeverityTxt}"></TextBlock>
                            <TextBlock Foreground="Black" FontSize="22" Margin="5,0,5,0" Text="Raised at "></TextBlock>
                            <TextBlock Foreground="Black" FontSize="22" Margin="5,0,5,0" Text="{Binding Path=Raised}"></TextBlock>
                        </StackPanel>

                        <Ellipse Grid.Row="0" Grid.Column="1" Margin="5,0,5,0" x:Name="StatusEllipse" Height="50" Width="50" Fill="{Binding Path = Colour}" />

                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>

        </ListBox>


    </StackPanel>
</Grid>

</phone:PhoneApplicationPage>

The other bindings work fine, but when i try to change from an int to a string the binding shows up as nothing.

2

There are 2 best solutions below

3
On BEST ANSWER

Firstly, RootObject should implement INotifyPorpertyChanged interface, so that bindings will work properly.

Having done that you should remove public field, and add a new property called severityTxt(BTW it should be called SeverityText according to the C# naming convention) with only get accessor.

The code will be like this:

public class RootObject : INotifyPropertyChanged
{
    private int serverity;

    private string areaDescription;

    private string raised;

    public int Severity 
    {
        get
        {
            return serverity;
        }
        set
        {
            serverity = value;
            NotifyPropertyChanged("Severity");
            NotifyPropertyChanged("SeverityTxt");
        }
    }

    public string AreaDescription 
    {
        get
        {
            return areaDescription;
        }
        set
        {
            areaDescription = value;
            NotifyPropertyChanged("AreaDescription");
        }
    }

    public string Raised 
    {
        get
        {
            return raised;
        }
        set
        {
            raised = value;
            NotifyPropertyChanged("Raised");
        }
    }

    public string SeverityTxt
    {
        get 
        {
            switch (Severity)
            {
                case 1:
                    return "Severe";
                case 2:
                    return "Warning";
                case 3:
                    return "Alert";
                default:
                    return string.Empty;
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

With such implementation you should bind not to severityTxt but to SeverityTxt. It's the basic solution, for more solid code you should consider using MVVM framework, such as MVVM Light and\or IValueConverter's.

0
On

I guess there is no problems with Enums (if I got what do you want):

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
   <ListView Name="TestListView">

   </ListView>
</Window>

Code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        TestListView.ItemsSource = new[] {Severity.Severe, Severity.Alert, Severity.Warning};
    }

    enum Severity
    {
        Severe = 1,
        Warning = 2,
        Alert = 3,
        None = 4
    }
}

result:

enter image description here

you can convert easy ints into enums, for examaple

TestListView.ItemsSource = new[] {1, 2, 3}.Select(i => (Severity) i);