首页 > 解决方案 > UWP - 如果数据源已更改,如何保存 ListViewItem 状态?

问题描述

我对listviewItem有一个问题,就是当您更改数据时,如果他们这样做了,但是当您单击另一个项目时它们没有保存在界面中

将文本框绑定到 listviewItem 时会出现此问题

主页.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
        }

模型: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; }

    } 
}

正如我所说的问题,因为我正在执行绑定,但是在执行 ListNotas.SelectionChanged 时,保存在 json 文件中的值已更改,但它们不会保留在 listviewitem 中,尽管绑定是在 Keydown 事件中而不是在 ListNotas . 选择已更改。

问题: https ://i.imgur.com/IGcd8iz.gif

我想要实现的目标: https ://i.imgur.com/KnkbQw9.gif

标签: c#xamllistviewuwp

解决方案


UWP - 如果数据源已更改,如何保存 ListViewItem 状态?

问题是您在Titulo_KeyDown事件中重复设置绑定。根据您的要求,您可以绑定 ListView SelectItem 一次。更多信息请参考以下步骤:

视图模型

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>

隐藏代码 (将数据写入 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

    }
}

这是示例项目


推荐阅读