0

You want the current data in the json file to be displayed in the listview without updating the list again or losing the SelectedInex

I already tried many ways but nothing works, it only works if you update the listview completely from ItemsSource but if I do it the selectedIndex is lost

MainPage.Xaml

<Grid RequestedTheme="Light">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
             <RowDefinition Height="818*" />

        </Grid.RowDefinitions>
        <TextBox
            x:Name="titulo"
            Grid.Row="0"
            FontSize="40"
            PlaceholderText="Ingresa tu titulo"
            Text="{Binding SelectedItem.title, ElementName=listNotas}"
            TextChanged="Titulo_TextChanged" />

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <ListView
                x:Name="listNotas"
                Width="450"
                Background="DimGray"
                SelectedItem="{Binding titulo.Text, Mode=TwoWay}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding title, Mode=TwoWay}" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <RichEditBox
                x:Name="editor"
                Width="760"
                HorizontalAlignment="Stretch" />
        </StackPanel>

MainPage.xaml.cs

 public ObservableCollection<Notes> mynotes = new ObservableCollection<Notes>();

        public string editpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Notas.json" );
        public MainPage()
        {
            this.InitializeComponent();

            // Load data of Notas.json to Listview
            using (StreamReader file = File.OpenText(editpath))
            {
                var json = file.ReadToEnd();
                baseNotes mainnotes = JsonConvert.DeserializeObject<baseNotes>(json);

                foreach (var item in mainnotes.notes)
                {
                    mynotes.Add(new Notes { title = item.title });
                }
                listNotas.ItemsSource = null;
                listNotas.ItemsSource = mynotes;
                listNotas.SelectedIndex = 0;
            } 
        }


        private void Titulo_TextChanged(object sender, TextChangedEventArgs e)
        { 
            // Saving textbox text to title value in json file
            string json = File.ReadAllText(editpath);
            dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
            int indice = listNotas.SelectedIndex;
            jsonObj["notes"][indice]["title"] = titulo.Text;

            string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj);
            File.WriteAllText(editpath, output);
            // Show json file text in RicheditBox
            editor.TextDocument.SetText(Windows.UI.Text.TextSetOptions.None, output);

        }

Model class: Notes.cs

public class Notes
    {
        public int created { get; set; }
       public string title { get; set; }


        public string text { get; set; }
        public int id { get; set; }
        public int updated { get; set; }
    }

    public class baseNotes
    {
        public List<Notes> notes { get; set; }
    }

json sample: Notas.json

{
  "notes": [
    {
      "created": 4352346,
      "title": "but not refresh listview values",
      "text": "fdsgfgsd fsgf sgtryt",
      "id": 432542,
      "updated": 23524
    },
    {
      "created": 4352346,
      "title": "this new value",
      "text": "fdsgfgsd fsgf sgtryt",
      "id": 432542,
      "updated": 23524
    },
    {
      "created": 4352346,
      "title": "changing value",
      "text": "fdsgfgsd fsgf sgtryt",
      "id": 432542,
      "updated": 23524
    }
  ]
}

Please do not know what else to do, I have been with this for 2 days, any kind of help, however minimal, will be great

Aqui una imagen:

https://i.stack.imgur.com/I4k4E.gif

as you see when writing in the textbox the changes if they are saved in the json file but they are not shown in the listview if you update it yes, but I want the changes to be displayed without updating

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
fausdev
  • 65
  • 8
  • You have an ObservableCollection, so far so good, but nothing triggers changes in your collection. I would consider a FileSystemWatcher and some coding that updates your collection when the underlying file changes – Cleptus Aug 30 '19 at 00:59
  • this is the goal i want to achieve https://i.imgur.com/cNWfGoo.gif – fausdev Aug 30 '19 at 00:59
  • I know what you want, but you are doing wrong two different things. a) You must implement `IPropertyChanged` and raise the property changed event when the tile is changed in your `Notes` class. b) You are never modifing your `ObservableCollection mynotes` but only writting its content to disk. That being said, I would suggest you checking other answers, especially MVVM ones like this [related, almost duplicated, one](https://stackoverflow.com/questions/22253211/wpf-two-way-binding-not-working). – Cleptus Aug 30 '19 at 01:57

1 Answers1

0

First,you need to implement INotifyPropertyChanged and subscribe the PropertyChanged event.In this case,the title property is observable.When your title changed or UI text changed,it will receive the notification to update.

public class Notes: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    public int created { get; set; }
    private string myTitle;
    public string title {
        get {
            return myTitle;
        }
        set {
            myTitle = value;
            OnPropertyChanged();
            }
        }


    public string text { get; set; }
    public int id { get; set; }
    public int updated { get; set; }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Then,the Binding mode of the TextBox should be TwoWay and UpdateSourceTrigger should be PropertyChanged.This means if you want the source to be updated as you type, you need to set the UpdateSourceTrigger of the binding to PropertyChanged.In this case,when you type into the TextBox,it will notification the title it bound with and the textBlock in the listView will also update.

.xaml:

<TextBox x:Name="titulo"
         Grid.Row="0"
         FontSize="40"
         PlaceholderText="Ingresa tu titulo"
         Text="{Binding SelectedItem.title, ElementName=listNotas,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
         TextChanged="Titulo_TextChanged" />
Faywang - MSFT
  • 5,798
  • 1
  • 5
  • 8
  • That is pretty much what I said in my comment and why I linked answers with similar solutions to yours – Cleptus Aug 30 '19 at 09:23
  • thanks, I could apply all the steps to everyone, but it only works for the first element `Text="{x:Bind Mynotes[0].title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"` How can I make it go through the entire array like this:    `Text =" {x: Bind Mynotes [ListNotas.SeletedIndex] .title, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged} "` but it does not allow me, please is the only thing I need – fausdev Aug 30 '19 at 11:12
  • I finally made it work and I skip another problem post it here:https://stackoverflow.com/questions/57731893/uwp-how-to-save-listviewitem-state-if-the-data-source-has-changed – fausdev Aug 30 '19 at 19:00