问题
I'm experiencing a very strange behavior of the RadListView for WinForms when I need to create a progress bar inside a listview's cell. It initially creates cells with progress bars but when I scroll the listview left and right, the progress bar elements move to the left one column.
Here is my code to insert create cell with progress bar:
_processingList = new RadListView();
_processingList.CellCreating += new ListViewCellElementCreatingEventHandler(_list_CellCreating);
_processingList.ViewType = ListViewType.DetailsView;
_processingList.Dock = System.Windows.Forms.DockStyle.Fill;
_processingList.HeaderHeight = 16;
_processingList.Columns.Add("Source");
_processingList.Columns.Add("Dir");
_processingList.Columns.Add("Destination");
_processingListProgressColumn = new ListViewDetailColumn("Progress", "");
_processingList.Columns.Add(_processingListProgressColumn);
_processingList.Columns.Add("Size");
_processingList.Columns.Add("Priority");
_processingList.Columns.Add("Status");
_processingList.Columns.Add("Start Time");
_processingList.Columns.Add("Elapsed");
_processingList.Columns.Add("Left");
...
void _list_CellCreating(object sender, ListViewCellElementCreatingEventArgs e)
{
DetailListViewDataCellElement dataCell = e.CellElement as DetailListViewDataCellElement;
if (dataCell != null && dataCell.Data == _processingListProgressColumn)
{
e.CellElement = new ProgressBarCellElement(dataCell.RowElement, dataCell.Data);
}
}
class ProgressBarCellElement : DetailListViewDataCellElement
{
private RadProgressBarElement progressBar;
public ProgressBarCellElement(DetailListViewVisualItem owner, ListViewDetailColumn column)
: base(owner, column)
{
}
protected override void CreateChildElements()
{
base.CreateChildElements();
this.progressBar = new RadProgressBarElement();
this.progressBar.StretchHorizontally = this.progressBar.StretchVertically = true;
this.Children.Add(this.progressBar);
}
public override void Synchronize()
{
base.Synchronize();
this.Text = "";
try
{
this.progressBar.Value1 = Convert.ToInt32(this.Row[this.column]);
}
catch { }
}
protected override Type ThemeEffectiveType
{
get
{
return base.ThemeEffectiveType;
}
}
}
Can someone have good explanation or point me to how to the right way to create the RadListView with ProgressBar inside some cells?
回答1:
RadListView uses virtualization for its cells in details view, so cells are being reused during operations like scrolling. To handle this case, you should first specify which column your cells should work with and also, you should set a default cell for the rest of the cases. Here is a complete example:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
InitializeComponent();
radListView1 = new RadListView();
radListView1.Parent = this;
this.Controls.SetChildIndex(radListView1, 0);
radListView1.CellCreating += new ListViewCellElementCreatingEventHandler(_list_CellCreating);
radListView1.ViewType = ListViewType.DetailsView;
radListView1.Dock = System.Windows.Forms.DockStyle.Fill;
radListView1.HeaderHeight = 16;
radListView1.Columns.Add("Source");
radListView1.Columns.Add("Dir");
radListView1.Columns.Add("Destination");
_processingListProgressColumn = new ListViewDetailColumn("Progress", "");
radListView1.Columns.Add(_processingListProgressColumn);
radListView1.Columns.Add("Size");
radListView1.Columns.Add("Priority");
radListView1.Columns.Add("Status");
radListView1.Columns.Add("Start Time");
radListView1.Columns.Add("Elapsed");
radListView1.Columns.Add("Left");
for (int i = 0; i < 60; i++)
{
radListView1.Items.Add("src", "dir", "dest", i * 1.14, "123", "high", "stat", "start", "elapsed", "left");
}
}
ListViewDetailColumn _processingListProgressColumn;
private void _list_CellCreating(object sender, ListViewCellElementCreatingEventArgs e)
{
DetailListViewDataCellElement dataCell = e.CellElement as DetailListViewDataCellElement;
if (dataCell != null)
{
if (dataCell.Data == _processingListProgressColumn)
{
e.CellElement = new ProgressBarCellElement(dataCell.RowElement, dataCell.Data);
}
else
{
e.CellElement = new DefaultCellElement(dataCell.RowElement, dataCell.Data);
}
}
}
class DefaultCellElement : DetailListViewDataCellElement
{
public DefaultCellElement(DetailListViewVisualItem owner, ListViewDetailColumn column) :
base(owner, column)
{
}
public override bool IsCompatible(ListViewDetailColumn data, object context)
{
return data.Name != "Progress";
}
protected override Type ThemeEffectiveType
{
get
{
return base.ThemeEffectiveType;
}
}
}
class ProgressBarCellElement : DetailListViewDataCellElement
{
private RadProgressBarElement progressBar;
public ProgressBarCellElement(DetailListViewVisualItem owner, ListViewDetailColumn column)
: base(owner, column)
{
}
public override bool IsCompatible(ListViewDetailColumn data, object context)
{
return data.Name == "Progress";
}
protected override void CreateChildElements()
{
base.CreateChildElements();
this.progressBar = new RadProgressBarElement();
this.progressBar.StretchHorizontally = this.progressBar.StretchVertically = true;
this.Children.Add(this.progressBar);
}
public override void Synchronize()
{
base.Synchronize();
this.Text = "";
try
{
this.progressBar.Value1 = Convert.ToInt32(this.Row[this.column]);
}
catch { }
}
protected override Type ThemeEffectiveType
{
get
{
return base.ThemeEffectiveType;
}
}
}
来源:https://stackoverflow.com/questions/25187177/radlistview-has-strange-behavior-when-creating-custom-cell-element-with-progress