WP8 get Grid (content panel) height in run time - c#

I have a basic question. I have my MainPage.xaml code like this,
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" Foreground="Black" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
</Grid>
</Grid>
In my MainPage.xaml.cs file,
public MainPage()
{
InitializeComponent();
MessageBox.Show(ContentPanel.Height.ToString());
}
My message box returns NaN value but I would like to get a specific value rather than indefinite value.
Thanks.

you should check the actual height of your content panel in the Loaded event. In the constructor it will be NaN because the actual values are not yet determined...

Based on the suggestions,
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(DisplayMessage);
}
void DisplayMessage(object sender, RoutedEventArgs e)
{
MessageBox.Show(ContentPanel.ActualHeight.ToString());
}
This returns me height of my content panel.
Thanks.

Related

Displaying multiple controls at once

I'm developing a UI with the WPF framework and MVVM.
This is the grid while loading:
image of the grid while displaying
This is the UI after the rendering has finished:
image of the grid when rendering is finished
So, as an example, the 3rd column isn't active and will collapse. But the user can see the whole building off the UI in the mainwindow.
Every view I've got is depending on the viewmodel. But also the controls got their own viewmodel. When I take my information together in one control, WPF is getting the information and draws the whole control, for example my tablecontrol. It´s a selfmade control, that is taking data and displays the data in a grid. Because it's one control, the whole grid is loaded in the background and displayed at once. When I make my own grid, because my tablecontrol can't handle the data, every control in the grid is displayed one after one and the grid is slowly displayed on the mainwindow.
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
.
.
.
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
.
.
.
</Grid.RowDefinitions>
<unitControls:Label Grid.Row="1" Grid.Column="0" Text="{Binding xx}"/>
<unitControls:Label Grid.Row="1" Grid.Column="1" Text="{Binding xx}"/>
<unitControls:Label Grid.Row="1" Grid.Column="2" Text="{Binding xx}"/>
.
.
.
<unitControls:Label Grid.Row="7" Grid.Column="7" Text="{Binding xx}"/>
<unitControls:Label Grid.Row="7" Grid.Column="8" Text="{Binding xx}"/>
<unitControls:Label Grid.Row="7" Grid.Column="9" Text="{Binding xx}"/>
<Grid>
Is there a way to display the whole content in one view at once? I tried to manipulate the dispatcher in the viewmodel, but nothing helped.
Try something like this:
XAML
<Window x:Class="Example.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Button Content="Collect data" Click="OnCollectData" DockPanel.Dock="Top"/>
<ContentControl x:Name="HostControl"/>
</DockPanel>
</Window>
CS
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private async void OnCollectData(object sender, RoutedEventArgs e)
{
var data = await CollectDataAsync();
HostControl.Content = new MyCustomGridControl(data);
}
private async Task<GridDataHolder> CollectDataAsync()
{
GridDataHolder result = null;
await Task.Run(() =>
{
// Collect the logical data on the thread pool
result = GetGridData();
});
return result;
}
}
You can put the HostControl with a ProgressBar in a Grid and play with the Visibility property of the ProgressBar to improve the user experience.

Frame navigation issue on Back button in Drawer Layout Windows Phone 8.1(Universal) WinRT

I want to use drawer layout in my app for hamburger but since my app have more than 30 pages having the drawer template declared on each page is not feasible hence I wanted to have the drawer layout as master page with a child/content page inside for which I have written below code with frame tag to navigate to page on click of menu in drawer layout.
Below is my XAML
<Grid x:Name="Rootlayout">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- title bar-->
<Grid x:Name="TitleBar" Height="50" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="SkyBlue">
<Image Source="/Assets/fs-logo.png" Height="50" HorizontalAlignment="Left" Margin="10,0,0,0"/>
</Grid>
<!--Drawer Layout-->
<drawer:DrawerLayout x:Name="DrawerLayout" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<Grid>
<Frame x:Name="contentFrame" />
</Grid>
<Grid x:Name="listFragment" FlowDirection="LeftToRight" >
<ListView x:Name="listItem" SelectionChanged="listItem_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="20" Foreground="Black" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</drawer:DrawerLayout>
</Grid>
While the behavior is exactly as I want but there is problem with hardware back button as when it's pressed the application gets exit. Even I have handle back button press event using following code is app.xaml.cs
//Below code of line in app constructor & it's method defination
#if WINDOWS_PHONE_APP
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
#endif
#if WINDOWS_PHONE_APP
void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (frame != null && frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
#endif
Can anyone help me how to resolve this issue of back button or is there any other way i can utilize drawer layout by which I don't have to write the drawer layout xaml code on each page. One way is using usercontrol but since the content grid is part of drawerlayout I'm not able to figure out how to club my usercontrol & my normal page xaml. Please help thanx in advance
You are checking CanGoBack on the wrong frame.
The Window.Current.Content is your base frame containing the DrawerLayout. What you actually want to address is the contentFrame inside of it.
So what you really want to look at is:
(Window.Current.Content as RootPage)?.Frame.CanGoBack
Where RootPage is the name of your Page for the Xaml you posted in your question.

WPF shrink other conent when Expander is Expanded

Whenever Expander is expanded I would like to shrink grid cell above containing ListBox, so that you can always access every ListItem(if the listbox's grid cell would not shrink, lowest part would be inacessible). To illustrate:
item item *scrollbar*
item -> item *scrollbar*
item expanderItems
expander expander
I found bunch of threads for resizable expander, but none mentioning resizing other content. The problem is, grid containing listbox in 1st row and expander in 2nd with 2nd row Height set to Auto do not resize itself when expander is expanded.
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
I managed to code an ugly workaround using Expanded/Collapsed events:
private void Expander_Expanded(object sender, System.Windows.RoutedEventArgs e)
{
//grid1.Height is named content of expander
this.LayoutRoot.RowDefinitions[1].Height = new GridLength(this.LayoutRoot.RowDefinitions[1].ActualHeight + grid1.Height, GridUnitType.Pixel);
this.LayoutRoot.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
}
What would be the proper way? Preferably with no code behind and more "automated".
EDIT: xaml
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Expander Header="Expander" Margin="0" Grid.Row="1" VerticalAlignment="Bottom" Height="23" Panel.ZIndex="1" ExpandDirection="Up" Grid.RowSpan="2" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">
<Grid x:Name="grid1" Background="#FF762CF7" Height="100" Margin="0,-100,0,0"/>
</Expander>
<ListBox Margin="0" Background="#19FFFFFF">
<Button Height="150" Width="100"/>
<Button Height="150" Width="100"/>
<Button Height="150" Width="100"/>
</ListBox>
<Grid Margin="0" Grid.Row="1" Background="#FFAEFFAE"/>
<Grid Margin="0" Background="#FFFFD8D8"/>
</Grid>
The main problem you have is setting the Height property of the Expander. It changes its height when you expand it. But if you are setting it, it has to respect the height you gave it and cannot properly expand.
Instead of setting the Height, I would set the MinHeight (or completely remove height constraints, depending on what you want to do).
Additionally you should remove the Margin of the grid inside the expander.

pivot page in windows phone 8 LoadedPivot event not firing?

i just started with generic forms for windows phone 8 development.
No i want to test if a certain pivotitem is selected, then it should fire a function to load a grid into that pivot item.
here is my xaml and my code so far
XAML:
<phone:Pivot Name="mainpivot" Title="MY APPLICATION" LoadingPivotItem="mainpivot_LoadingPivotItem" LoadedPivotItem="mainpivot_LoadedPivotItem_1">
<!--Pivot item one-->
<phone:PivotItem Name="staticpivot" Header="static">
<!--Double line list with text wrapping-->
<Grid Name="staticGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Name="txtUsername" Grid.Column="1" Height="70"></TextBox>
<TextBox Name="txtPassword" Grid.Row="1" Height="70" Grid.Column="1"></TextBox>
<TextBox Name="txtdescription" Grid.Row="2" Height="150" Grid.Column="1" TextWrapping="Wrap"></TextBox>
<TextBlock Height="40" Text="USERNAME" HorizontalAlignment="Center"></TextBlock>
<TextBlock Height="40" Text="PASSWORD" HorizontalAlignment="Center" Grid.Row="1"></TextBlock>
<TextBlock Height="40" Text="DESCRIPTION" HorizontalAlignment="Center" Grid.Row="2"></TextBlock>
<Button Grid.Row="4" Grid.ColumnSpan="2" Tap="Button_Tap">SAVE DATA</Button>
</Grid>
</phone:PivotItem>
<!--Pivot item two-->
<phone:PivotItem x:Name="genericpivot" Header="generic">
<!--Double line list no text wrapping-->
</phone:PivotItem>
</phone:Pivot>
as you can see the 2nd pivot has nothing in it, i am going to populate it dynamically with controls.
the problem is here in the code :
private void mainpivot_LoadedPivotItem_1(object sender, PivotItemEventArgs e)
{
if (e.Item.Name == "genericpivot")
{
loadDetailForPivot();
}
}
this function does not fire when i debug and put a breakpoint there.
can anyone tell my why? or give a link that explains it.
regards
To clarify, are you trying to populate the selected pivot item once it's selected?
I believe what you are after is picking up a change to the pivot controls selectedindex, such as (VB.net, sorry):
Private Sub PivotItem_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles PivotItem.SelectionChanged
If PivotItem.SelectedIndex = 1 Then LoadDetailForPivot
End Sub
However...why do you not load the controls beforehand? Wouldn't that be quicker (i.e. no delay while things are loaded as the user pivots). I did this on a previous app and the pivoting was jerky as a result.

How to change BitmapEffect in custom WPF control via C# code

I have a custom control type like: <Grid> ... </Grid> and Grid.BitmapEffect property. How can I change BitmapEffetc in this Control (Grid) via C# code (e.g. on event)?
Code sample - part of custom control:
[...]
<Grid Background="#FFE5AA">
<Grid.RowDefinitions>
<RowDefinition Height="62*"/>
<RowDefinition Height="15*"/>
<RowDefinition Height="23*"/>
</Grid.RowDefinitions>
<Grid.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="#459E5A" GlowSize="13" Noise="0" Opacity="0.9" />
</Grid.BitmapEffect>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" BorderBrush="#F5B903" BorderThickness="1,1,1,1" >
</Border>
[...]
Then in Window.xaml:
<controls:MyControl Name="Control1" Cursor="Hand" MouseDown="Control1_MouseDown" />
Then in C#:
private void Control1_MouseDown(object sender, MouseButtonEventArgs e)
{
//there i want to change Control1.BitmapEffect
}
myGrid.BitmapEffect = null;
PS: Note that BitmapEffect is considered obsolete and that Effect should be used instead.
Here's an example based on your sample which works perfectly fine (here on my machine): As soon as I click within the Grid, the effect disappears.
XAML:
<Window x:Class="WpfCsApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid Background="#FFE5AA" Margin="10" MouseDown="Grid_MouseDown" x:Name="myGrid">
<Grid.RowDefinitions>
<RowDefinition Height="62*"/>
<RowDefinition Height="15*"/>
<RowDefinition Height="23*"/>
</Grid.RowDefinitions>
<Grid.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="#459E5A" GlowSize="13" Noise="0" Opacity="0.9" />
</Grid.BitmapEffect>
<Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" BorderBrush="#F5B903" BorderThickness="1,1,1,1" >
<TextBlock>Test</TextBlock>
</Border>
</Grid>
</Window>
Codebehind:
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
}
private void Grid_MouseDown(object sender, MouseButtonEventArgs e) {
myGrid.BitmapEffect = null;
}
}
In your example you write: //there i want to change Control1.BitmapEffect. Note that you need to change the BitmapEffect of the Grid, not the BitmapEffect of Control1.
OK, I've got it! I was add an DepencyProperty 'GlowSize' and simply change size of glow via it. :) Works perfect.
Different effects are listed here : Different BitmapEffect

Categories

Resources