【问题标题】:UWP - How to save ListViewItem state if the data source has changed?UWP - 如果数据源已更改,如何保存 ListViewItem 状态?
【发布时间】:2020-01-04 00:17:42
【问题描述】:

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

文本框绑定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
        }

模型: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# xaml listview uwp


    【解决方案1】:

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

    这是示例project

    【讨论】:

    • 您好,感谢您的回答,下载您的示例效果很好,但是当我尝试在我的 MainPage.xaml 项目中实现它时,您不想识别集成的 ViewModel进入 MainPage.xaml.cs Image Error
    • 我已经解决了,我已经把ViewModel放在MainPage Classjj里面了,再次感谢您的回复
    • 没关系,祝你有美好的一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多