Click here to Skip to main content
15,898,943 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:

XML
<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:
XML
<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 :

C#
	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;
				//HoldedHeight = lb.ActualHeight / lb.Items.Count;
				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;
		}



		/// <summary>
		/// The <see cref="Data" /> dependency property's name.
		/// </summary>
		public const string DataPropertyName = "Data";

		/// <summary>
		/// Gets or sets the value of the <see cref="Data" />
		/// property. This is a dependency property.
		/// </summary>
		public TestDataItem Data
		{
			get
			{
				return (TestDataItem)GetValue(DataProperty);
			}
			set
			{
				SetValue(DataProperty, value);
			}
		}

		/// <summary>
		/// Identifies the <see cref="Data" /> dependency property.
		/// </summary>
		public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
			DataPropertyName,
			typeof(TestDataItem),
			typeof(TestPanel),
			new PropertyMetadata(null));
	}
</t></listbox>

C#
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;
    }
}

C#
    public class TestDataItem
{
    public string Channel
    {
        get;
        set;
    }

}


The main page is :
C#
	public partial class MainPage : PhoneApplicationPage
	{
		// Constructor
		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
Posted
Updated 26-Oct-11 21:13pm
v7

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900