2
我正在为另一个应用程序制作配置编辑器,并且正在使用反射从配置类中提取可编辑的字段。以下类是我的各种“DataTypeViewModels”的基类,并显示了我如何获取和设置适当的属性。如何在这种情况下模拟可观察集合的影响?
public abstract class DataTypeViewModel<T> : ViewModelBase
{
Func<T> getFunction;
Action<T> setAction;
public const string ValuePropertyName = "Value";
public string Label { get; set; }
public T Value
{
get
{
return getFunction.Invoke();
}
set
{
if (getFunction.Invoke().Equals(value))
{
return;
}
setAction.Invoke(value);
// Update bindings, no broadcast
RaisePropertyChanged(ValuePropertyName);
}
}
/// <summary>
/// Initializes a new instance of the StringViewModel class.
/// </summary>
public DataTypeViewModel(string sectionName, string label)
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
Label = label;
getFunction = new Func<T>(() =>
{
return (T)Settings.Instance.GetType().GetProperty(sectionName).PropertyType.
GetProperty(label).GetValue(Settings.Instance.GetType().GetProperty(sectionName).GetValue(Settings.Instance, null), null);
});
setAction = new Action<T>(value =>
{
Settings.Instance.GetType().GetProperty(sectionName).PropertyType.GetProperty(label).
SetValue(Settings.Instance.GetType().GetProperty(sectionName).GetValue(Settings.Instance, null), value, null);
});
}
}
}
这部分以我想要的方式工作,下一部分是字符串列表中的示例DataTypeViewModel。
public class StringListViewModel : DataTypeViewModel<ICollection<string>>
{
/// <summary>
/// The <see cref="RemoveItemCommand" /> property's name.
/// </summary>
public const string RemoveItemCommandPropertyName = "RemoveItemCommand";
private RelayCommand<string> _removeItemCommand = null;
public ObservableCollection<string> ObservableValue { get; set; }
/// <summary>
/// Gets the RemoveItemCommand property.
/// TODO Update documentation:
/// Changes to that property's value raise the PropertyChanged event.
/// This property's value is broadcasted by the Messenger's default instance when it changes.
/// </summary>
public RelayCommand<string> RemoveItemCommand
{
get
{
return _removeItemCommand;
}
set
{
if (_removeItemCommand == value)
{
return;
}
var oldValue = _removeItemCommand;
_removeItemCommand = value;
// Update bindings, no broadcast
RaisePropertyChanged(RemoveItemCommandPropertyName);
}
}
/// <summary>
/// The <see cref="AddItemCommand" /> property's name.
/// </summary>
public const string AddItemCommandPropertyName = "AddItemCommand";
private RelayCommand<string> _addItemCommand = null;
/// <summary>
/// Gets the AddItemCommand property.
/// TODO Update documentation:
/// Changes to that property's value raise the PropertyChanged event.
/// This property's value is broadcasted by the Messenger's default instance when it changes.
/// </summary>
public RelayCommand<string> AddItemCommand
{
get
{
return _addItemCommand;
}
set
{
if (_addItemCommand == value)
{
return;
}
var oldValue = _addItemCommand;
_addItemCommand = value;
// Update bindings, no broadcast
RaisePropertyChanged(AddItemCommandPropertyName);
}
}
/// <summary>
/// Initializes a new instance of the StringListViewModel class.
/// </summary>
public StringListViewModel(string sectionName, string label) : base(sectionName, label)
{
ObservableValue = new ObservableCollection<string>(Value);
AddItemCommand = new RelayCommand<string>(param =>
{
if (param != string.Empty)
{
Value.Add(param);
ObservableValue.Add(param);
}
});
RemoveItemCommand = new RelayCommand<string>(param =>
{
if (param != null)
{
Value.Remove(param);
ObservableValue.Remove(param);
}
});
}
}
正如你可以在构造函数中看到,我现在有“价值”镜像到一个名为“ObservableValue”新的ObservableCollection,然后通过在XAML一个ListView必然。它的工作方式很好,但克隆List似乎是一件很难办的事情。虽然绑定到的价值,我已经尝试添加:
RaisePropertyChanged("Value");
到AddItemCommand和RemoveItemCommand,但这不起作用,ListView控件将不会更新。什么是正确的方法来做到这一点?
我尝试这样做,NotifyPropertyChanged无一不没有按预期工作。 – MGSoto 2010-04-20 15:59:01
看看上面的编辑,这是你做的? – 2010-04-21 00:41:16
我在适当的调用中添加了add和remove命令,但是我没有创建自定义集合,我使用了基类中的属性,该基类是从子类中模板化的List。 – MGSoto 2010-04-27 23:22:21