How to create a custom panel?
Hi,
I want to create a custom panel, like this:
then I find nothing to override in Noesis::Panel
I want to create a custom panel, like this:
Code: Select all
//WPF
class RadialPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
foreach(UIElement elem in Children)
{
elem.Measure(new Size(float.PositiveInfinity, float.PositiveInfinity));
}
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
if(Children.Count == 0)
{
return finalSize;
}
double Angle = 0;
double AngularSpace = (360.0 / Children.Count) * (Math.PI / 180);
double radiusX = finalSize.Width / 2.4;
double radiusY = finalSize.Height / 2.4;
foreach(UIElement elem in Children)
{
Point childPosition = new Point(Math.Cos(Angle) * radiusX, -Math.Sin(Angle) * radiusY);
Point ActualPoint = new Point(finalSize.Width * 0.5 + childPosition.X - elem.DesiredSize.Width * 0.5, finalSize.Height * 0.5 + childPosition.Y - elem.DesiredSize.Height * 0.5);
elem.Arrange(new Rect(ActualPoint.X, ActualPoint.Y, elem.DesiredSize.Width, elem.DesiredSize.Height));
Angle += AngularSpace;
}
return finalSize;
//return base.ArrangeOverride(finalSize);
}
}
Re: How to create a custom panel?
Not sure to be following you here. Panel inherits from FrameworkElement, and that class contains the virtual functions MeasureOverride and ArrangeOverride.
Re: How to create a custom panel?
Hi,Not sure to be following you here. Panel inherits from FrameworkElement, and that class contains the virtual functions MeasureOverride and ArrangeOverride.
I override the 2 functions in c++, it works for normal way, but does not show Items if I set it as the PanelTemplate of the ListBox
Code: Select all
Size RadialPanel::MeasureOverride(const Size& availableSize)
{
for (int i = 0; i < GetChildren()->Count(); ++i)
{
UIElement* elem = (UIElement*)(GetChildren()->Get(i));
if (elem != nullptr)
{
elem->Measure(Size::Infinite());
}
}
return Panel::MeasureOverride(availableSize);
}
Size RadialPanel::ArrangeOverride(const Size& finalSize)
{
if (GetChildren()->Count() == 0)
{
return finalSize;
}
float Angle = 0;
float AngularSpace = (360.f / GetChildren()->Count()) * DegToRad;
float radiusX = finalSize.width / 2.4f;
float radiusY = finalSize.height / 2.4;
for (int i = 0; i < GetChildren()->Count(); ++i)
{
UIElement* elem = (UIElement*)(GetChildren()->Get(i));
if (elem != nullptr)
{
Point ChildPosition(Cos(Angle) * radiusX, -Sin(Angle) * radiusY);
Point ActualPoint(finalSize.width * 0.5f + ChildPosition.x - elem->GetDesiredSize().width * 0.5f,
finalSize.height * 0.5f + ChildPosition.y - elem->GetDesiredSize().height * 0.5f);
elem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));
Angle += AngularSpace;
}
}
return finalSize;
}
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: How to create a custom panel?
In MeasureOverride your panel should return the minimal size it requires to show all its children inside the available space.
If you return base class MeasureOverride it will return a size of 0x0, which can lead to receiving a 0x0 size in ArrangeOverride, for example if panel is centered, in a Viewbox, or inside a ScrollViewer (as it occurs when it is used as ItemsPanel of a ListBox).
If you return base class MeasureOverride it will return a size of 0x0, which can lead to receiving a 0x0 size in ArrangeOverride, for example if panel is centered, in a Viewbox, or inside a ScrollViewer (as it occurs when it is used as ItemsPanel of a ListBox).
Re: How to create a custom panel?
Hi,In MeasureOverride your panel should return the minimal size it requires to show all its children inside the available space.
If you return base class MeasureOverride it will return a size of 0x0, which can lead to receiving a 0x0 size in ArrangeOverride, for example if panel is centered, in a Viewbox, or inside a ScrollViewer (as it occurs when it is used as ItemsPanel of a ListBox).
I set the custom panel size to 200*200, and I can seee the background is right size. In debug, the ArrangeOverride param is 200 * 200 too.
Code: Select all
<ItemsControl ItemsSource="{Binding SpellTargetList}"
Visibility="{Binding bShowSpellTargetPanel, Converter={StaticResource BoolToVisible}, FallbackValue=Visible}" Canvas.Left="300" Canvas.Top="310" Foreground="#FF917A7A" Background="#FFF7E6AB">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:RadialPanel Width="200" Height="200" Background="#FFFDCECE"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding DisplayName}"
Command="{Binding DataContext.SelectSpellTarget, ElementName=SpellPanelControl}"
CommandParameter="{Binding UniqueID}"
Background="#FF7C7C7C" Margin="3" FontFamily="{StaticResource Font_KaiTi}" Foreground="#FF27B7FB" FontSize="18" Width="50" Height="50"></Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
-
-
sfernandez
Site Admin
- Posts: 3363
- Joined:
Re: How to create a custom panel?
I found in your ArrangeOverride code this:
Our C++ Rect constructor taking 4 floats expects (left, top, right, bottom), different from WPF C# Rect constructor, sorry for that.
You can write the following instead:
Code: Select all
elem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));You can write the following instead:
Code: Select all
elem->Arrange(Rect(ActualPoint, elem->GetDesiredSize()));Re: How to create a custom panel?
Thank you.I found in your ArrangeOverride code this:Our C++ Rect constructor taking 4 floats expects (left, top, right, bottom), different from WPF C# Rect constructor, sorry for that.Code: Select allelem->Arrange(Rect(ActualPoint.x, ActualPoint.y, elem->GetDesiredSize().width, elem->GetDesiredSize().height));
You can write the following instead:Code: Select allelem->Arrange(Rect(ActualPoint, elem->GetDesiredSize()));
Re: How to create a custom panel?
I am marking this as solved.
Who is online
Users browsing this forum: Bing [Bot] and 5 guests