我在Visual Basic和C#中都在NET Framework 3.5中维护一些旧的WinForms,但我很难绑定到POCO数据类。
我得到了这个(使用INotifyPropertyChanged):
public string DisplayUnits
{
get { return _displayUnits; }
set
{
_displayUnits = value;
NotifyChange("DisplayUnits");
}
}
public string SetUnit
{
get { return _setUnit; }
set
{
_setUnit = value;
NotifyChange("SetUnit");
}
}
设置SetUnit不是问题,因为我得到了这个:
ComboxBoxUnits.DataBindings.Add("SelectedItem", data, "SetUnit", False, DataSourceUpdateMode.OnPropertyChanged)
这是有效的,因为它是一个字符串对一个字符串,但数据。DisplayUnits是一个字符串,即"英寸;英尺;码;毫米;厘米;米",目前组合框的填充方式如下:
ComboBoxUnits.Items.AddRange(data.DisplayUnits.Split(";"));
此外,用户还可以通过一种方式在该列表中添加和删除项目。所以当我需要做项目的时候。添加或项目。移除,如何将其绑定到DisplayUnits属性,并在组合框项目列表更新时触发更改?
相反,它必须是像WPF中那样的双向数据绑定。当数据。DisplayUnits由另一个过程更新(即:ft2;yard2;cm2;m2),当它们变为不同的"产品"时(就像第一个产品将测量长度,第二个产品将度量近似面积),我需要更新UI以反映组合中的这些变化。项目
在MVVM中,我可以尝试使用ITypeConverter(Convert,ConvertBack),但我认为WinForms不支持它;但是必须有一种方法来格式化组合框。项到数据类的POCO属性,对于要转换回的POCO类,对于Winform也是如此。
有什么想法吗?
更新:澄清一下——我之所以将它保留在纯旧CLR对象(POCO)中,是因为"数据"将用于XML序列化。XML文件将使用PIC处理器下载到自定义机器上。";"用于解析。因此,DisplayUnit的格式必须为"in;ft;yd"。
此外,这将在VS2008中编译,因为我们使用的触摸屏正在运行WinCE 6.5。一半将在C#中,而另一半将在Visual Basic中。
我不知道我是否理解你,但根据我的理解,你需要设置组合框的DataSource属性。这就是我在Winforms:中的做法
添加一个定义组合框的DataSource:的类
class ComboDataSource
{
// Display is the property shown as item in your ComboBox (DisplayMember)
public string Display { get; set; }
// you could also add a ValueMember ID or something
}
添加一个方法,将DisplayUnits作为参数,并将字符串剪切为字符串数组。遍历字符串,创建并添加您的ComboDataSource。将列表分配给ComboxBoxUnits。DataSource。定义DisplayMember(当然它是ComboDataSource的Display属性)
private void UpdateDataSource(string data)
{
var split = data.Split(';');
List<ComboDataSource> list = new List<ComboDataSource>();
foreach (var item in split)
list.Add(new ComboDataSource() { Display = item });
ComboxBoxUnits.DataSource = list;
ComboxBoxUnits.DisplayMember = "Display";
}
在这个例子中,我创建了一个类来包装DisplayUnits和SetUnit属性。(我没有实现SetUnit)实现INotifyPropertyChanged接口。
class Data : INotifyPropertyChanged
{
private string _displayUnits;
public string DisplayUnits
{
get { return _displayUnits; }
set
{
_displayUnits = value;
OnPropertyChanged("DisplayUnits");
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后,您可以在代码中创建Data对象。像这样的。。。
Data data = new Data();
订阅PropertyChangedEvent。。。
data.PropertyChanged +=(sender, args) => UpdateDataSource(data.DisplayUnits); // pass in the DisplayUnits
设置数据。。。
data.DisplayUnits = "cm;km;feet;yard";
PropertyChanged事件将激发并更新DataSource,从而更新组合框中显示的项。
希望这能帮助。。。
更新:从组合框中删除项目并重新绑定。(按钮点击或其他)
ComboDataSource selectedItem = comboBox1.SelectedItem as ComboDataSource;
if(selectedItem == null)
throw new NullReferenceException("selectedItem");
// get the DataSource back from the ComboBox
List<ComboDataSource> dataSource = comboBox1.DataSource as List<ComboDataSource>;
if (dataSource != null)
{
// remove it from the datasource
dataSource.Remove(selectedItem);
// so this is pretty 'straight forward' and certainly not best practice, but we put the datasource back up again the same way we have set it
string[] comboBoxItems = dataSource.Select(item => item.Display).ToArray();
// join the string (f.e. 'km;cm;feet') and update it again
string newDataSource = string.Join(";", comboBoxItems);
UpdateDataSource(newDataSource);
}