I met a very strange problem recently.
I want to control the ListBoxItem's render by myself for a very complicated ListBox,
when i finish the work , I found that the first appearance is exactly what i wanna, but when i scroll down the ListBox, I was confused and frustrated to see the orders of ListBoxItem is not in order at all.
Now I created a new empty similiar project and tested ,the result is same.( In Windows Phone 7 is , But in WPF application everything is well.)
V1:
<ListBox x:Name="ListBoxTest">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Channel}" Width="1000"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
V1 is just binding the property to special control, in this way ,everything is well .
V2:
<ListBox x:Name="ListBoxTest">
<ListBox.ItemTemplate>
<DataTemplate>
<local:TestPanel Data="{Binding}" HoldedHeight="100"></local:TestPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and the TestPannel is defined as :
public class TestPanel : StackPanel
{
private bool _beginLoaded;
private bool _isLoaded;
private ListBox _parentListBox;
public TestPanel()
: base()
{
this.Loaded += TestPanel_Loaded;
}
void TestPanel_Loaded(object sender, RoutedEventArgs e)
{
if (Data != null)
{
System.Diagnostics.Debug.WriteLine("ProgramsPanel_Loaded with {0}", Data.Channel);
}
else
{
System.Diagnostics.Debug.WriteLine("ProgramsPanel_Loaded with NULL data");
}
if (_beginLoaded || _isLoaded)
return;
_beginLoaded = true;
InitializeWidthParent();
this.Children.Clear();
Show(Data, HoldedWidth, HoldedHeight);
_isLoaded = true;
}
private void InitializeWidthParent()
{
_parentListBox = FindParent<listbox>(this);
if (_parentListBox != null)
{
HoldedWidth = _parentListBox.ActualWidth;
System.Diagnostics.Debug.WriteLine("GetParentWidth succeed. ListBox width is {0}, height is {1}",
_parentListBox.ActualWidth, _parentListBox.ActualHeight);
}
}
static T FindParent<t>(DependencyObject d) where T : DependencyObject
{
DependencyObject parent = d;
while (parent != null)
{
parent = VisualTreeHelper.GetParent(parent);
if (parent != null && (parent.GetType() == typeof(T)))
{
return parent as T;
}
}
return parent as T;
}
private void Show(TestDataItem data, double holdedwidth, double holdedheight)
{
System.Diagnostics.Debug.WriteLine("Enter ShowPrograms");
if (data == null)
return;
if (!holdedwidth.IsValid() || !holdedheight.IsValid())
return;
#region Stand at Left Side (Channel Name and Image)
TextBlock tb = new TextBlock() { FontSize = 32, Text = data.Channel, HorizontalAlignment = HorizontalAlignment.Center };
this.Children.Add(tb);
#endregion
#region Right Side
#endregion
}
public double HoldedWidth
{
get;
set;
}
public double HoldedHeight
{
get;
set;
}
public const string DataPropertyName = "Data";
public TestDataItem Data
{
get
{
return (TestDataItem)GetValue(DataProperty);
}
set
{
SetValue(DataProperty, value);
}
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
DataPropertyName,
typeof(TestDataItem),
typeof(TestPanel),
new PropertyMetadata(null));
}
</t></listbox>
public static partial class Extentsions
{
public static bool IsValid(this double width)
{
if (double.IsNaN(width)
|| Math.Abs(width) < 0.1)
{
return false;
}
return true;
}
}
public class TestDataItem
{
public string Channel
{
get;
set;
}
}
The main page is :
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<testdataitem> source = new ObservableCollection<testdataitem>();
ListBoxTest.ItemsSource = source;
for (int i = 0; i < 50; i++)
{
source.Add(new TestDataItem() { Channel = i.ToString() });
}
}
}
</testdataitem></testdataitem>
so why after I use V2 the ListBoxItems will be disorderly rendered, and how could I solve this problem?
Thanks,
Sparkling