我有ViewState
持有List<T>
public List<AwesomeInt> MyList
{
get { return ((List<int>)ViewState["MyIntList"]).Select(i => new AwesomeInt(i)).ToList(); }
set { ViewState["MyIntList"] = value.GetIntegers(); }
}
现在,当我打电话给MyList.Add(new AwesomeInt(3))
时,列表不会保留更改。
我认为这是因为.ToList()
中的get
正在创建一个新的List对象,因此永远不会调用set
,因此永远不会保存在ViewState中。
我之前通过
解决了这个问题.Select/.ToList()
转换。.Add
或.Remove
函数
用等号重新初始化List
。然而,如果类不可序列化并且我无法控制它,有时1.
是不切实际的,2.
有点难看,因为我必须先将它复制到temp,然后添加,然后重新分配,或者使用Concat
来添加单个项目。
有更好的方法吗?
答案 0 :(得分:0)
好的,下面是一个功能齐全的控制台应用程序,可以为您提供所需的功能。我利用泛型,以便您可以构建任何类型的周围集合 - 但序列化更基本的东西。请记住,我在set
中没有要写入的真实视图状态,但您可以解决此问题。
另外请记住,我在相当短的时间内写了这篇文章(例如 20分钟),因此可能存在优化(例如 set
一般来说,ViewState
属性并不是必需的,因为此解决方案会修改基础的基本数据源。)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static List<int> _viewState = new List<int>();
static RawCollection<AwesomeInt, int> ViewState
{
get { return new RawCollection<AwesomeInt, int>(_viewState); }
set { _viewState = value.RawData; }
}
static void Main(string[] args)
{
ViewState.Add(new AwesomeInt(1));
ViewState.Add(new AwesomeInt(2));
WriteViewState();
ViewState[0].Val = 5;
WriteViewState();
ViewState.RemoveAt(0);
WriteViewState();
for (int i = 10; i < 15; i++)
{
ViewState.Add(new AwesomeInt(i));
}
WriteViewState();
}
private static void WriteViewState()
{
for (int i = 0; i < ViewState.Count; i++)
{
Console.WriteLine("The value at index {0} is {1}.", i, ViewState[i].Val);
}
Console.WriteLine();
Console.WriteLine();
}
}
public class RawCollection<T, K> : Collection<T>
{
private List<K> _data;
public RawCollection(List<K> data)
{
foreach (var i in data)
{
var o = (T)Activator.CreateInstance(typeof(T), i);
var oI = o as IRawData<K>;
oI.RawValueChanged += (sender) =>
{
_data[this.IndexOf((T)sender)] = sender.Val;
};
this.Add(o);
}
_data = data;
}
public List<K> RawData
{
get
{
return new List<K>(
this.Items.Select(
i => ((IRawData<K>)i).Val));
}
}
protected override void ClearItems()
{
base.ClearItems();
if (_data == null) { return; }
_data.Clear();
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
if (_data == null) { return; }
_data.Insert(index, ((IRawData<K>)item).Val);
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
if (_data == null) { return; }
_data.RemoveAt(index);
}
protected override void SetItem(int index, T item)
{
base.SetItem(index, item);
if (_data == null) { return; }
_data[index] = ((IRawData<K>)item).Val;
}
}
public class AwesomeInt : IRawData<int>
{
public AwesomeInt(int i)
{
_val = i;
}
private int _val;
public int Val
{
get { return _val; }
set
{
_val = value;
OnRawValueChanged();
}
}
public event Action<IRawData<int>> RawValueChanged;
protected virtual void OnRawValueChanged()
{
if (RawValueChanged != null)
{
RawValueChanged(this);
}
}
}
public interface IRawData<T> : INotifyRawValueChanged<T>
{
T Val { get; set; }
}
public interface INotifyRawValueChanged<T>
{
event Action<IRawData<T>> RawValueChanged;
}
}