I have a problem where I display objects which have variable length lists of strings. As I scroll down a list of a large number of them, the row heights aren't being resized as the row gets reused.
Here is the basic approach:
- The ColumnTemplate for the string list property has a StackPanel.
- In the LoadingRow event, I add a TextBlock for each string in the list to the StackPanel
- In the UnloadingRow event, I clear the StackPanel.
However, if a row with an object that has say 10 strings gets reused by an object with a list of less (even 0) strings, the row Height does not reset. If I set the RowHeight in UnloadingRow to 0 or Nan, it doesn't help. If I set it to an absolute value
(say 25), it stays that way and doesn't auto-size to the number of strings in the property when they're added in LoadingRow.
Is there any way to just reset a row and clear everything (height, and everything else)? I guess I can figure out the row heights necessary for each number of items in the list (or do math), but it seems like a hacky workaround.
I've posted a simplified repro scenario that just has a Document object with a list of Authors that I randomly generate either 0 or 10 authors for. Load the app and scroll up and down fast (drag the scroller with your mouse) and then you'll see rows where
the AuthorCount = 0, but the size of the row is sized for the 10 string size.
A second issue is as you do this, you can sometimes drag the scoller to the bottom and not be on the last row (Doc1499). This is harder to repro, but I can make it happen fairly regularly by moving around a lot on the scroll bar and alternating back to
selecting rows.
public
class
Document
{
public
string Name {
get;
set; }
public
int AuthorCount
{
get {
return Authors.Count; }
}
public
List<string> Authors
{
get {
return authors; }
}
private
List<string> authors =
new
List<string>();
public
static
List<Document> GetDocs(int
count)
{
List<Document> documents =
new
List<Document>();
for (int i = 0; i < count; i++)
{
Document doc =
new
Document() { Name =
"Doc" + i.ToString() };
AddAuthors(doc, i);
documents.Add(doc);
}
return documents;
}
private
static
void AddAuthors(Document document,
int count)
{
// Do either 0 or 10 authors randomly
Random r =
new
Random(count);
int authorCount = (r.Next(2) == 0 ? 0 : 10);
for (int i = 0; i < authorCount; i++)
{
document.Authors.Add("Author" + i.ToString());
}
}
}
KeithRZaaz
0 Points
4 Posts
Resetting Row Height on Unloading row?
Jul 15, 2008 11:26 PM | LINK
I have a problem where I display objects which have variable length lists of strings. As I scroll down a list of a large number of them, the row heights aren't being resized as the row gets reused.
Here is the basic approach:
- The ColumnTemplate for the string list property has a StackPanel.
- In the LoadingRow event, I add a TextBlock for each string in the list to the StackPanel
- In the UnloadingRow event, I clear the StackPanel.
However, if a row with an object that has say 10 strings gets reused by an object with a list of less (even 0) strings, the row Height does not reset. If I set the RowHeight in UnloadingRow to 0 or Nan, it doesn't help. If I set it to an absolute value (say 25), it stays that way and doesn't auto-size to the number of strings in the property when they're added in LoadingRow.
Is there any way to just reset a row and clear everything (height, and everything else)? I guess I can figure out the row heights necessary for each number of items in the list (or do math), but it seems like a hacky workaround.
I've posted a simplified repro scenario that just has a Document object with a list of Authors that I randomly generate either 0 or 10 authors for. Load the app and scroll up and down fast (drag the scroller with your mouse) and then you'll see rows where the AuthorCount = 0, but the size of the row is sized for the 10 string size.
A second issue is as you do this, you can sometimes drag the scoller to the bottom and not be on the last row (Doc1499). This is harder to repro, but I can make it happen fairly regularly by moving around a lot on the scroll bar and alternating back to selecting rows.
datagrid datagrid column binding source delete edit DataGrid Beta2
KeithRZaaz
0 Points
4 Posts
Re: Resetting Row Height on Unloading row?
Jul 15, 2008 11:34 PM | LINK
Page.xaml has the grid:
<Grid x:Name="LayoutRoot" Background="White"><my:DataGrid x:Name="DataGrid1" AutoGenerateColumns="False" /></Grid>
Page.xaml.cs:
public partial class Page : UserControl { public Page(){
InitializeComponent();
this.DataGrid1.Columns.Add(DataGridColumns.Instance.NameColumn);
this.DataGrid1.Columns.Add(DataGridColumns.Instance.AuthorCountColumn);
this.DataGrid1.Columns.Add(DataGridColumns.Instance.AuthorsColumn);
this.DataGrid1.LoadingRow += new EventHandler<DataGridRowEventArgs>(DataGrid1_LoadingRow);
this.DataGrid1.UnloadingRow += new EventHandler<DataGridRowEventArgs>(DataGrid1_UnloadingRow);
this.DataGrid1.ItemsSource = Document.GetDocs(1500);
} void DataGrid1_UnloadingRow(object sender, DataGridRowEventArgs e)
{
// Get Stack panel for AuthorsColumn.
StackPanel panel = DataGridColumns.Instance.AuthorsColumn.GetCellContent(e.Row) as StackPanel;
// Clear just to make sure.
panel.Children.Clear();
} void DataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
{
// Get Stack panel for AuthorsColumn.
StackPanel panel = DataGridColumns.Instance.AuthorsColumn.GetCellContent(e.Row) as StackPanel;
// Clear just to make sure.
panel.Children.Clear();
// Add authors
Document doc = (Document)e.Row.DataContext;
foreach (string author in doc.Authors)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = author;
panel.Children.Add(textBlock);
}
}
}
KeithRZaaz
0 Points
4 Posts
Re: Resetting Row Height on Unloading row?
Jul 15, 2008 11:36 PM | LINK
public class Document
{
public string Name { get; set; }
public int AuthorCount
{
get { return Authors.Count; }
} public List<string> Authors
{
get { return authors; }
} private List<string> authors = new List<string>(); public static List<Document> GetDocs(int count)
{
List<Document> documents = new List<Document>();
for (int i = 0; i < count; i++)
{
Document doc = new Document() { Name = "Doc" + i.ToString() };
AddAuthors(doc, i);
documents.Add(doc);
}
return documents;
} private static void AddAuthors(Document document, int count)
{
// Do either 0 or 10 authors randomly
Random r = new Random(count);
int authorCount = (r.Next(2) == 0 ? 0 : 10);
for (int i = 0; i < authorCount; i++)
{
document.Authors.Add("Author" + i.ToString());
}
}
}
KeithRZaaz
0 Points
4 Posts
Re: Resetting Row Height on Unloading row?
Jul 15, 2008 11:40 PM | LINK
DataGridColumns.cs:
public class DataGridColumns{
private DataGridColumns()
{} public static readonly DataGridColumns Instance = new DataGridColumns(); private string defaultNamespace = "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\""; public DataTemplate StackPanelTemplate
{
get
{
if (stackPanelTemplate == null)
{
stackPanelTemplate = (DataTemplate)XamlReader.Load(String.Format(
"<DataTemplate {0}><StackPanel VerticalAlignment='Center' Margin='4,8,4,4' Orientation=\"Vertical\" /></DataTemplate>", defaultNamespace));
}
return stackPanelTemplate;
}
}
private DataTemplate stackPanelTemplate; public DataGridColumn NameColumn
{
get{
if (nameColumn == null)
{
nameColumn = new DataGridTextColumn();
nameColumn.Header = "Document Name";
nameColumn.IsReadOnly = true;
nameColumn.DisplayMemberBinding = new System.Windows.Data.Binding("Name");
}
return nameColumn;
}
}
public DataGridTextColumn nameColumn; public DataGridColumn AuthorCountColumn
{
get
{
if (authorCountColumn == null)
{
authorCountColumn = new DataGridTextColumn();
authorCountColumn.Header = "Author Count";
authorCountColumn.IsReadOnly = true;
authorCountColumn.DisplayMemberBinding = new System.Windows.Data.Binding("AuthorCount");
}
return authorCountColumn;
}
}
public DataGridTextColumn authorCountColumn; public DataGridTemplateColumn AuthorsColumn
{
get
{
if (authorsColumn == null)
{
authorsColumn = new DataGridTemplateColumn();
authorsColumn.Header = "Authors";
authorsColumn.IsReadOnly = true;
authorsColumn.CellTemplate = StackPanelTemplate;
}
return authorsColumn;
}
}
public DataGridTemplateColumn authorsColumn;
}
}