我计划将我的应用程序中的一组相同对象转储给用户。
我需要一个控件,在向其添加数据后,可以通过编程方式更改特定单元格和行中的数据。
目前我正在使用ListView,并且我用我的对象填充了它:
我的目标是:
public class TestData
{
public string Name {get;set;}
public double Force {get;set;}
public double PreTriggerVolt {get;set;}
public double PreTriggerCurr {get;set;}
public double TriggerVolt {get;set;}
public double TriggerCurr {get;set;}
public double PostTriggerVolt {get;set;}
public double PostTriggerCurr {get;set;}
}
Type列由我自己在ListView中进行硬编码:P
我在桌子上会有很多这样的内容。
其中一个问题是,有时,例如,在收集数据后,TriggerVolt
应添加/减去所有或部分offset value
值。您可能会说最好清除ListView,使用foreach或其他任何对象进行更改,然后重新调整ListView。但是,有没有办法直接指出特定的行列?例如,我真的想要一些我可以命名为单元格并稍后调用它的东西。喜欢:
Cell[J6][PreTriggerVolt] == 0.01212
(只是一般性的想法)
另一个问题是按名称,优质或...对数据进行排序。例如,如果我对Pin
列进行排序,则实际引脚名称下面的行可能占主导地位。我的意思是Force : -0.1
例如...然后我的listview中的所有东西都崩溃了!这将是一个巨大的混乱。
您可能已经了解了很多关于ListView的其他问题。
我想知道实现这一目标的最佳方式是什么。
感谢。
答案 0 :(得分:2)
您应该考虑将控件直接绑定到模型,而不是构建列表视图。这是Binding in WinForms的一个很好的教程。根据您要对显示的数据执行的操作,DataGrid可能是更好的选择(特别是如果您希望用户能够编辑数据,即使使用自定义控件 - 请参阅this tutorial)。
设置绑定后,您需要在模型类上实现INotifyPropertyChanged接口,以通知绑定框架属性已更改。
public class TestData: INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
this.NotifyPropertyChanged("Name");
}
}
// I only included one property for simplicity. You of course will need to do this
// for every property in the test model
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
答案 1 :(得分:1)
在我看来,这不是最佳实践,它非常脆弱,在TestData Structure或UI附近嗅探,这都是改变时间。关注点的封装/分离也很糟糕。
绑定到Testdata的用户控件,然后绑定到它们列表的tablelayout面板会更好。这样你就可以处理TestDataUIControl中对TestDataProperties的更改,并在TestDataUIControlList中添加/删除和refesh
所以twidlle有补偿就是说
BindingList<TestData>
对TestData实例的更改会触发UI控件处理它的事件并更新相关的UI控件。
干净整洁,将TestData与控件分开,特别是如果你创建一个接口,例如ITestData for it。