UWP - How to save ListViewItem state if the data source has changed?

非 Y 不嫁゛ 提交于 2019-12-11 17:01:42

问题


I have a problem with the listviewItem, is that when you change the data if they do it but they are not saved in the interface when you click on another item

This problem happens when binding the textbox to the listviewItem

MainPage.xaml

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


        </Grid.RowDefinitions>
        <TextBox
            x:Name="titulo"
            Grid.Row="0"
            FontSize="40"
            PlaceholderText="Ingresa tu titulo"
                KeyDown="Titulo_KeyDown"
            />

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <ListView
                x:Name="listNotas"
                Width="450"
                Background="DimGray"
                SelectionChanged="ListNotas_SelectionChanged">

                <ListView.ItemTemplate>
                    <DataTemplate >
                        <StackPanel>
                          <TextBlock Text="{Binding title, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <RichEditBox
                x:Name="editor"
                Width="760"
                HorizontalAlignment="Stretch" />
        </StackPanel>
        <GridView
            Name="stpanel"
            Grid.Row="2"
            Height="50">
            <TextBlock Text="" Name="Tester"/>
        </GridView>

MainPage.xaml.cs

  public string editpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Notas.json" );
        public ObservableCollection<Notes> Mynotes; 




        public MainPage()
        {
            this.InitializeComponent();

            // Load data of Notas.json to Listview
            LoadUpdate();

        }

        private void LoadUpdate()
        {
            using (StreamReader file = File.OpenText(editpath))
            {
                var json = file.ReadToEnd();
                baseNotes mainnotes = JsonConvert.DeserializeObject<baseNotes>(json);
                Mynotes = new ObservableCollection<Notes>();

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

        private void ListNotas_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string json = File.ReadAllText(editpath);
            dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
           titulo.Text = jsonObj["notes"][listNotas.SelectedIndex]["title"];

        }

        private void Titulo_KeyDown(object sender, KeyRoutedEventArgs e)
        {
            #region
            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);            


            //Problem
            Binding myBinding = new Binding();
            myBinding.Source = Mynotes[indice];
            myBinding.Path = new PropertyPath("title");
            myBinding.Mode = BindingMode.TwoWay;
            myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(titulo, TextBox.TextProperty, myBinding);
            #endregion
        }

Model: Notes.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Controls;

namespace Realtimejsonedit
{

    public class Notes : INotifyPropertyChanged
    {
        public int created { get; set; }


       //public string title { get; set; }

        private string Title;

        public string title
        {
            get { return Title; }
            set {
                Title = value;
                NotifyPropertyChanged("title");

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

        public event PropertyChangedEventHandler PropertyChanged;

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

            }
        }


    }

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

    } 
}

as I say the problem as I am doing the binding but when executing ListNotas.SelectionChanged the values that were saved in the json file are changed, but they do not remain in the listviewitem, although the binding is in the Keydown event and not in ListNotas. SelectionChanged.

the problem: https://i.imgur.com/IGcd8iz.gif

What I want to achieve: https://i.imgur.com/KnkbQw9.gif


回答1:


UWP - How to save ListViewItem state if the data source has changed?

The problem is that you set bind repeatedly in Titulo_KeyDown event. For your requirement, you could bind ListView SelectItem once. For more please refer the following steps:

ViewModel

public class ViewModel : INotifyPropertyChanged
{
    public string editpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Notas.json");
    public ObservableCollection<Notes> Mynotes { get; set; }
    public ViewModel()
    {
        LoadUpdate();
        SetSelectIndex(0);
    }

    private void SetSelectIndex(int index)
    {
        SelectItem = Mynotes[index];
    }
    private void LoadUpdate()
    {
        using (StreamReader file = File.OpenText(editpath))
        {
            var json = file.ReadToEnd();
            baseNotes mainnotes = JsonConvert.DeserializeObject<baseNotes>(json);
            Mynotes = new ObservableCollection<Notes>();

            foreach (var item in mainnotes.notes)
            {
                Mynotes.Add(new Notes { title = item.title });
            }

        }
    }

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

    private Notes _selectItem;

    public event PropertyChangedEventHandler PropertyChanged;

    public Notes SelectItem
    {
        get
        {
            return _selectItem;
        }
        set
        {
            _selectItem = value;
            OnPropertyChanged();
        }
    }
}

Xaml

<Page.DataContext>
    <local:ViewModel />
</Page.DataContext>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
        <RowDefinition Height="818*" />
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <TextBox
        x:Name="titulo"
        Grid.Row="0"
        FontSize="40"
        PlaceholderText="Ingresa tu titulo"
        Text="{Binding SelectItem.title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
        TextChanged="Titulo_TextChanged"
        />

    <StackPanel Grid.Row="1" Orientation="Horizontal">
        <ListView
            x:Name="listNotas"
            Width="450"
            Background="DimGray"
            ItemsSource="{Binding Mynotes}"
            SelectedItem="{Binding SelectItem, Mode=TwoWay}"
            >

            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <RichEditBox
            x:Name="editor"
            Width="760"
            HorizontalAlignment="Stretch"
            />
    </StackPanel>
    <GridView
        Name="stpanel"
        Grid.Row="2"
        Height="50"
        >
        <TextBlock Name="Tester" Text="" />
    </GridView>
</Grid>

Code behind (write the data to json)

public sealed partial class MainPage : Page
{

    private dynamic jsonObj;
    public string editpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Notas.json");
    public ObservableCollection<Notes> Mynotes;
    public MainPage()
    {
        this.InitializeComponent();

        string json = File.ReadAllText(editpath);
        jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

    }

    private void Titulo_TextChanged(object sender, TextChangedEventArgs e)
    {
        #region

        int indice = listNotas.SelectedIndex;
        jsonObj["notes"][indice]["title"] = titulo.Text;
        string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj);
        editor.TextDocument.SetText(Windows.UI.Text.TextSetOptions.None, output);
        File.WriteAllText(editpath, output);
        #endregion

    }
}

This is sample project.



来源:https://stackoverflow.com/questions/57731893/uwp-how-to-save-listviewitem-state-if-the-data-source-has-changed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!