首页 > 解决方案 > json文件修改时如何实时更改listview值

问题描述

您希望 json 文件中的当前数据显示在列表视图中,而无需再次更新列表或丢失 SelectedInex

我已经尝试了很多方法,但没有任何效果,它只有在您完全从 ItemsSource 更新列表视图时才有效,但如果我这样做,则 selectedIndex 会丢失

主页.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);

        }

模型类: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 样本: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
    }
  ]
}

请不知道还能做什么,我已经用了 2 天了,任何形式的帮助,无论多么微不足道,都会很棒

Aqui una 图像:

https://i.imgur.com/3619gg3.gif

正如您在文本框中写入时看到的那样,更改是否保存在 json 文件中,但如果您更新它,它们不会显示在列表视图中,但是我希望显示更改而不更新

标签: c#jsonlistviewuwpuwp-xaml

解决方案


首先,你需要实现INotifyPropertyChanged并订阅PropertyChanged事件。在这种情况下,title属性是可观察的。当你的标题改变或UI文本改变时,它会收到更新通知。

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));
    }
}

然后,TextBox的Binding模式应该是TwoWay,UpdateSourceTrigger应该是PropertyChanged。这意味着如果你想在你输入的时候更新源,你需要将绑定的UpdateSourceTrigger设置为PropertyChanged。在这种情况下,当你输入进入 TextBox,它会通知它绑定的标题,并且 listView 中的 textBlock 也会更新。

.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" />

推荐阅读