How to get Actual Size programmatically based on internal content?
I'm looking at dynamic menu's that can be clamped to within screen space
but I can't get the ActualHeight/Width to set the offsets.
I saw in an older thread that this depends on the UI being passed to the renderer first.
but it was never explained the process of doing such.
so I was wondering how I might be able to constrain the dimensions
based on internal content as ActualHeight returns 0?
but I can't get the ActualHeight/Width to set the offsets.
I saw in an older thread that this depends on the UI being passed to the renderer first.
but it was never explained the process of doing such.
so I was wondering how I might be able to constrain the dimensions
based on internal content as ActualHeight returns 0?
Code: Select all
Button origin = ((Noesis.Button)sender);
Point position = origin.PointToScreen(new Point(0f,26f));
Noesis.StackPanel Menu = new Noesis.StackPanel
{
Background = Brushes.Beige,
MinWidth = 150,
MaxWidth = 250,
MinHeight = 12,
CanVerticallyScroll = true
};
for (int i = 0; i < Singularity.random(3, 15); i++)
{
Menu.Children.Add(new Button
{
Focusable = false,
Content = Singularity.random(1, 200).ToString(),
Margin = Thickness.Parse("1")
//Padding = Thickness.Parse("15,5")
});
}
Debug.Log("HEIGHT: " + Menu.ActualHeight);
Debug.Log("WIDTH: " + Menu.ActualWidth);
position.X = Mathf.Clamp(position.X, 0, Screen.width - Menu.ActualWidth);
position.Y = Mathf.Clamp(position.Y, 0, Screen.height - Menu.ActualHeight);
Re: How to get Actual Size programmatically based on internal content?
I've been working on a data structure to handle the buttons but still, no progress on clamping elements to the view
I've moved code around so it should add to the uiRoot before calling ActualWidth
however, I need some sort of callback to the loaded event
this scopes outside what I'm familiar with in C#
I've moved code around so it should add to the uiRoot before calling ActualWidth
however, I need some sort of callback to the loaded event
this scopes outside what I'm familiar with in C#
Re: How to get Actual Size programmatically based on internal content?
Found a solution, the documentation doesn't give an example.
once it's added to the main UI, you add a .Loaded =+(){}'
once it's added to the main UI, you add a .Loaded =+(){}'
Code: Select all
DropMenu.Loaded += (object _sender, Noesis.RoutedEventArgs e) =>
{
Button origin = ((Noesis.Button)originalSender);
Point position = origin.PointToScreen(new Point(0f, 26f));
position.Y = Mathf.Clamp(position.Y, 0, uiRoot.ActualHeight - DropMenu.ActualHeight);
position.X = Mathf.Clamp(position.X, 0, uiRoot.ActualWidth - DropMenu.ActualWidth);
DropMenu.Margin = Thickness.Parse(position.X.ToString() + "," + position.Y.ToString() + ",0,0");
};
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: How to get Actual Size programmatically based on internal content?
Hi, sorry for the late answer.
ActualWidth and ActualHeight properties are calculated during the layout process in the UI Update, so they won't provide meaningful values just after element gets created or its size/position properties has changed. You can force an update by calling element.UpdateLayout(), or as you have done, after creating the element wait until Loaded event is raised.
But in this situation, couldn't you use a simple StackPanel with HorizontalAlignment="Right" and let the system handle the positioning?
And just a suggestion, instead of creating Thickness objects parsing a string, you can construct them like:
ActualWidth and ActualHeight properties are calculated during the layout process in the UI Update, so they won't provide meaningful values just after element gets created or its size/position properties has changed. You can force an update by calling element.UpdateLayout(), or as you have done, after creating the element wait until Loaded event is raised.
But in this situation, couldn't you use a simple StackPanel with HorizontalAlignment="Right" and let the system handle the positioning?
And just a suggestion, instead of creating Thickness objects parsing a string, you can construct them like:
Code: Select all
DropMenu.Margin = new Thickness(position.X, position.Y, 0, 0);
Re: How to get Actual Size programmatically based on internal content?
it actually uses stack panels already, but it's not a child of the initiator, as I am attempting to create menu's like you would in windows application where content needs to overlay other elements.
most of the information I was going with was based on my findings in the documentation and here in the forums.
it might be good to have both our codes added to the documentation as examples
Code: Select all
Noesis.StackPanel DropMenu = new Noesis.StackPanel
{
Background = Brushes.Beige,
MinWidth = 150,
MaxWidth = 250,
MinHeight = 12,
};
DropMenu.HorizontalAlignment = HorizontalAlignment.Left;
DropMenu.VerticalAlignment = VerticalAlignment.Top;
ActiveMenus.Add(DropMenu);
uiRoot.Children.Add(DropMenu);
it might be good to have both our codes added to the documentation as examples
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: How to get Actual Size programmatically based on internal content?
There are specific controls for that in Noesis, you can define a Menu with MenuItem children to show a popup with options. And it can be dynamically filled by binding the ItemsSource of the Menu and MenuItems with the corresponding data:I am attempting to create menu's like you would in windows application where content needs to overlay other elements.
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<HierarchicalDataTemplate x:Key="SubItemTemplate" ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding DisplayName}" />
</HierarchicalDataTemplate>
</UserControl.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}" ItemTemplate="{StaticResource SubItemTemplate}"/>
<Grid />
</DockPanel>
</UserControl>
Code: Select all
class MenuItemVM
{
public ObservableCollection<MenuItemVM> MenuItems { get; private set; }
public string DisplayName { get; private set; }
public MenuItemVM(string name)
{
MenuItems = new ObservableCollection<MenuItemVM>();
DisplayName = name;
}
}
Re: How to get Actual Size programmatically based on internal content?
to an extent, yes. but due to the nature of my project, I can't rely on XAML files as the content needs to change dynamically. either through user customization or live updates
so I'm attempting to do all this mostly in C#
I want to break away from the rigidity of the XAML files and the problems they come with, ie using blend.
and create a middle software that can be fed data objects to generate the GUI on demand.
so I'm attempting to do all this mostly in C#
I want to break away from the rigidity of the XAML files and the problems they come with, ie using blend.
and create a middle software that can be fed data objects to generate the GUI on demand.
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: How to get Actual Size programmatically based on internal content?
What I'm trying to say is that you can create a Menu control in code and feed it with a list of items and it will automatically populate and position the menu items for you. There is no need to manually create buttons and calculate positions, that is all already done by the layout system.
Everything that can be done in XAML can be written in code (or it should be, otherwise it is probably because of a bug or something missing in the API).
For example, following my previous code you can write this:
Everything that can be done in XAML can be written in code (or it should be, otherwise it is probably because of a bug or something missing in the API).
For example, following my previous code you can write this:
Code: Select all
Menu menu = new Menu();
menu.ItemsSource = menuItemsList;
menu.ItemTemplate = (DataTemplate)XamlReader.Parse(
"<HierarchicalDataTemplate ItemsSource=\"{Binding MenuItems}\">\n" +
" <TextBlock Text=\"{Binding DisplayName}\" />\n" +
"</HierarchicalDataTemplate>");
DockPanel.SetDock(menu, Dock.Top);
DockPanel panel = new DockPanel();
panel.Children.Add(menu);
What problems did you find working with Blend? We would like to know if there is something we can improve for future versions.I want to break away from the rigidity of the XAML files and the problems they come with, ie using blend.
Re: How to get Actual Size programmatically based on internal content?
Originally, I was looking at menu items, but realized that some content I would need in those span outside typical menu entries, such as volume controls and other tools.
so I moved to StackPanels - I will look at menu's again.
as for Blend, it's an overbearing application with tools and widgets that seem convoluted and impractical when you want basic elements on demand.
combine that with the user interface that looks like a broken powerpoint, it doesn't have a smooth workflow or decent user experience.
it also broke several things when attempting to merge and use it with the Unity workflow.
in the end, it wasn't worth it. especially since Noesis supports runtime building, which is perfect.
Ideally, what I want is to be able to create GUI with nested .dot notation, not move vectors and rulers around. it is backwards to what I would want when creating a GUI.
hopefully, when I'm done, I would like to submit my script to the samples so others can look at doing it programmatically
so I moved to StackPanels - I will look at menu's again.
as for Blend, it's an overbearing application with tools and widgets that seem convoluted and impractical when you want basic elements on demand.
combine that with the user interface that looks like a broken powerpoint, it doesn't have a smooth workflow or decent user experience.
it also broke several things when attempting to merge and use it with the Unity workflow.
in the end, it wasn't worth it. especially since Noesis supports runtime building, which is perfect.
Ideally, what I want is to be able to create GUI with nested .dot notation, not move vectors and rulers around. it is backwards to what I would want when creating a GUI.
hopefully, when I'm done, I would like to submit my script to the samples so others can look at doing it programmatically
Re: How to get Actual Size programmatically based on internal content?
That would be awesome!hopefully, when I'm done, I would like to submit my script to the samples so others can look at doing it programmatically
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 2 guests