UWP C# How to append .json file and to identify them in groups

71 views Asked by At

I am trying to create a usercontrol to display groups of items from json file on windows iot core.

I have a "Create Group" button. Once pressed, it will create 64 usercontrols with respective details and display in a scrollviewer. susequently i can edit individual items in any of the 64 usercontrol then save the json file.

I have my class for the usercontrol as follow;

I have having an issue on how to create different groups of the 64 items and append all in a same json file and to subsequently display them from selection of the mentioned different groups.

Please help thanks.

Group Class

[DataContract]
public class DecoderGroup
{
    [DataMember]
    public int groupID{ get; set; }
    [DataMember]
    public string groupName{ get; set; }
    [DataMember]
    public int cardAddress { get; set; }
    [DataMember]
    public bool enabled { get; set; }
    [DataMember]
    public int z1label { get; set; }
    [DataMember]
    public int z2label { get; set; }
    [DataMember]
    public int z3label { get; set; }
    [DataMember]
    public int z4label { get; set; }
    [DataMember]
    public bool zone1 { get; set; }
    [DataMember]
    public bool zone2 { get; set; }
    [DataMember]
    public bool zone3 { get; set; }
    [DataMember]
    public bool zone4 { get; set; }
    [DataMember]
    public List<byte> txData { get; set; }

    public DecoderGroup(int id, int address, int z1, int z2, int z3, int z4)
    {
        groupName = "Group";
        zone1 = false;
        zone2 = false;
        zone3 = false;
        zone4 = false;

        z1label = z1;
        z2label = z2;
        z3label = z3;
        z4label = z4;
    }
}

MainPage.xaml.cs

private void AddGroup_Click(object sender, RoutedEventArgs e)
    {
        ZonesList_Panel.Children.Clear();

        int groupid = 1;
        int cardadr;

        for (cardadr = 1; cardadr <= MAXCARDS; cardadr++)
        {
            var z4 = (4 * cardadr);
            var z3 = (4 * cardadr) - 1;
            var z2 = (4 * cardadr) - 2;
            var z1 = (4 * cardadr) - 3;

            DecoderGroupUserControl decoderGroupControl = new DecoderGroupUserControl(this, new DecoderGroup(groupid, cardadr, z1, z2, z3, z4));
            ZonesList_Panel.Children.Add(decoderGroupControl);
        }
    }

private async void SaveGroup_Click(object sender, RoutedEventArgs e)
        {
                await saveGroupsToJSON(getGroups());
            
        }

public async Task saveGroupsToJSON(List<DecoderGroup> groups)
        {
            var serializer = new DataContractJsonSerializer(typeof(List<DecoderGroup>));
            using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(DECODERGROUPS_FILE, CreationCollisionOption.OpenIfExists))
            {
                serializer.WriteObject(stream, groups);
            }
        }

    public List<DecoderGroup> getGroups()
    {
        List<DecoderGroup> ret = new List<DecoderGroup>();
        foreach (DecoderGroupUserControl u in ZonesList_Panel.Children)
        {
            //add condition for group ID
            ret.Add(u.decoderGroup);
        }
        return ret;
    }

UserControl

 public DecoderGroupUserControl(MainPage page, DecoderGroup group)
    {
        this.InitializeComponent();
        mainPage = page;
        this.decoderGroup = group;

        Z1Name.Text = group.z1label.ToString();
        Z2Name.Text = group.z2label.ToString();
        Z3Name.Text = group.z3label.ToString();
        Z4Name.Text = group.z4label.ToString();
    }
1

There are 1 answers

0
dear_vv On BEST ANSWER

It is recommended to use UserControl as the DateTemplate of ListView so that you don’t need to create multiple usercontrol and add them to the page. Then you could read json file and convert json objects to a collection, and you could use the collection as the Itemsource of ListView.

By implementing the INotifyPropertyChanged interface, TwoWay data binding could reflect the UI changes to the collection. Finally, you could write the changed collection to the json file.

Note that you need to download the Newtonsoft.Json to parse the json object via Manage NuGet Packages. Please refer to the following code.

MyUserControl1.xaml:

<UserControl
   ..>
   <Grid>
       <!--customize the usercontrol style-->
        <StackPanel>
            <StackPanel Orientation="Horizontal" >
                <TextBox Margin="0,0,20,0"  Text="{Binding Name,Mode=TwoWay}" BorderThickness="0"/>
                <TextBox Text="{Binding Job,Mode=TwoWay}" BorderThickness="0"/>
            </StackPanel>
            <TextBox Text="{Binding Age,Mode=TwoWay}" BorderThickness="0"/>
        </StackPanel>
    </Grid>
</UserControl>

MainPage.xaml:

<Page..>

    <Grid>
        <StackPanel>
            <ListView ItemsSource="{x:Bind Results,Mode=TwoWay}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:Person">
                    <local:MyUserControl1>                        
                    </local:MyUserControl1>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
            <Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click"/>
        </StackPanel>
    </Grid>
</Page>

MainPage.xaml.cs:

namespace WriteJson
{
    public sealed partial class MainPage : Page
    {
        public ObservableCollection<Person> Persons { get; set; }
        public ObservableCollection<Person> Results { get; set; }
        public string path;
        public MainPage()
        {
            this.InitializeComponent();
            CreateJsonFile();
            path = ApplicationData.Current.LocalFolder.Path + "\\info.json";    
            Results = JsonConvert.DeserializeObject<ObservableCollection<Person>>(File.ReadAllText(path));
            Debug.WriteLine("bind successfully");
        }  
       public async void CreateJsonFile()
        {
            //check if info.json exists, if it doesn't exist, create it
            StorageFolder folder = ApplicationData.Current.LocalFolder;
            StorageFile file;
            try
            {            
                file = await folder.GetFileAsync("info.json");
            }
            catch
            {
                await folder.CreateFileAsync("info.json");
                Persons = new ObservableCollection<Person>()
            {
                new Person(){Name="tom",Job="teacher",Age=24},
                new Person(){Name="lily",Job="nurse",Age=20},
                new Person(){Name="ming",Job="student",Age=26},
                new Person(){Name="kiki",Job="lawyer",Age=28},
                new Person(){Name="jack",Job="worker",Age=21},
            };

                path = ApplicationData.Current.LocalFolder.Path + "\\info.json";
                File.WriteAllText(path, JsonConvert.SerializeObject(Persons));
                Debug.WriteLine("create a json file successfully");
            }
          
        }
     
        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            File.WriteAllText(path, JsonConvert.SerializeObject(Results));
            Debug.WriteLine("save successfully");
        }
    }
    public class Person:INotifyPropertyChanged
    {
       private string name;
        private string job;
        private int age;
        public string Name 
        { 
            get { return name; } 
            set 
            {
                name = value;
                RaisePropertyChanged("Name");
            } 
        }
        public string Job
        {
            get { return job; }
            set
            {
                job = value;
                RaisePropertyChanged("Job");
            }
        }
        public int Age
        {
            get { return age; }
            set
            {
                age = value;
                RaisePropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyname=null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
        }
    }
}