WinRT ListView and ExpanderView issues - windows-runtime

After, what I thought was a successful porting of Windows Phone toolkit ExpanderView to WinRT, I noticed that it not working 100% as it should.
Here is what i'm trying to do:-
I have a ListView with the ItemsSource being databound, inside the ItemTemplate of this ListView there is a ExpanderView which I port???!!! The idea is that, I want the expander view to expand when I tap on the ListView item.
This per say, is happening BUT when the ExpanderView expands, it overlap the next ListView item, i.e ListViewItem Height is not changing. Why is that I really don't know. Been trying every possible idea I came up with to solve this but in vain :(
Can anyone helps me and guide me in the right direction?
Below is a link to a simple example (VS project with all the necessary code) to demo the problem
Simple Universal App to demo the problem
Thanks in advance

There are quite a few places where you have animations that are making layout changes. These animations are very UI-thread heavy, so require the property EnableDependentAnimations to be set to True. You can find more out about it here. You will likely need to go into the styles and manually change the VisualStates to make this change. One such example is:
In your ExpanderResource.xaml:
<VisualStateGroup x:Name="ExpansionStates">
<VisualStateGroup.Transitions>
<VisualTransition From="Collapsed"
GeneratedDuration="0:0:0.15" To="Expanded">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ItemsCanvas" EnableDependentAnimation="True">
<EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseOut}" KeyTime="0:0:0.00" Value="0" />
<EasingDoubleKeyFrame x:Name="CollapsedToExpandedKeyFrame" EasingFunction="{StaticResource QuadraticEaseOut}" KeyTime="0:0:0.15" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
</VisualStateGroup>
Note that the DoubleAnimationUsingKeyFrames targetting (FrameworkElement.Height) requires EnableDependentAnimations="True", as this affects the layout.
This is not the only place in that file that needs to be fixed. Further, I don't think it will solve all of your layout problems. It will get it property expanding the layout though.

Be sure you are using a stackpanel as your panel.
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Best of luck!

Related

I cannot apply a custom style for an AppBarButton inside a CommandBar in WP 8.1

I have a very specific question. I could not find any answers for this exact problem, so I used the trial and error method to pinpoint the problem. Here is an example code I have the problem with:
<Page.BottomAppBar>
<CommandBar x:Name="MainMenuCommandBar" ClosedDisplayMode="Minimal">
<CommandBar.PrimaryCommands>
<AppBarButton x:Name="otherCommandButton" Label="Egyéb" Icon="List" Click="otherCommandButton_Click" Style="{StaticResource appbarButton}">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem x:Name="SecondaryFlyout1" Text="Névjegy" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout2" Text="Adatbázis mentés" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout3" Text="Adatbázis visszaállítás" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout4" Text="Terminál törlése" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout5" Text="Jelszavas védelem" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout6" Text="Nyelv váltás" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout7" Text="Betűméret" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
<MenuFlyoutItem x:Name="SecondaryFlyout8" Text="Kilépés" Style="{StaticResource BottomAppBarFlyoutStyle}"/>
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
<AppBarButton x:Name="refreshCommandButton" Label="Frissítés(Bank)" Icon="Refresh" Style="{StaticResource appbarButton}"/>
<AppBarButton x:Name="syncCommandButton" Label="Szinkronizál(PC)" Icon="Sync" Style="{StaticResource appbarButton}"/>
</CommandBar.PrimaryCommands>
</CommandBar>
</Page.BottomAppBar>
I wanted to apply a custom style for the appbarbuttons inside a commandbar, because the text in the Labels are too long, and I can't see the whole text. So I thought, I will make the text smaller, or the appbarbutton wider. The designer showed me the changes, but when I run the program, nothing changes. The appbarbuttons use the default styling, no matter what I do. So the text don't get smaller when I run the program.
After this, I tried to pinpoint the problem. I tried to edit the template too, but the "edit a copy" command is grayed out. I thought this is weird, because I sweeped through MSDN, and there I saw that the appbarbuttons in fact has a style which I could edit. I copied the default style, made changes, applied it into my app.xaml as a custom style, but I met with the same problem as before. Nothing changed, no matter what I altered in the style. After all these failures, I put an appbarbutton OUTSIDE a commandbar. And at this case, everything works fine. I can edit a copy of the template, and the changes reflect when I run the program. Another weird case is, that the menuflyoutitems can be styled inside the commandbar.
Sorry for the lengthy explanations, I wanted to present what I know already. My question in short that, is there any way to style an appbarbutton inside a commandbar? Or if not, is there any alternative to create a custom commandbar?
The CommandBar on Windows Phone is system UI and cannot be customized by the app beyond setting it's foreground and background colors.
If you want to customize the individual buttons you'll need to implement your own panel for them instead of using the app bar. You can place a horizontal Stack Panel at the bottom of your page and include customized AppBarButtons in it. If you want it to shoe and hide you will need to set your own logic to detect the triggering input and then apply an animation to side it open and closed.

How to wrap a group of TextBlocks inside StackPanel?

This is my code.
<StackPanel Orientation="Horizontal">
<TextBlock Name="Link1" Text="this is link1"></TextBlock>
<TextBlock Name="Text1" Text=" some text "></TextBlock>
<TextBlock Name="Link2" Text="this is link2"></TextBlock>
<TextBlock Name="Text2" Text=" some other text "></TextBlock>
<TextBlock Name="Link3" Text="this is link3></TextBlock>
</StackPanel>
Now this StackPanel will go out of the screen. I want to wrap the contents of this to go into next line on screen end.
I am not using <Run> property of TextBlock for defining all this because I want to register Tap event for TextBlocks defined as Links in above code. Using Buttons and Hyperlinks is also not desired here. Also with Buttons I will be having the same issue of wrapping up the content.
I see three options here:
Use a RichTextBox
Hoist the WrapPanel from the Windows Phone Toolkit
Write your own Panel
I think #1 should be the preferred approach, assuming you can make it fit the requirements. A RichTextBox can contain plain text inline with Hyperlinks -- the latter does not expose a Tap event, but it does have Click which may suffice.
Failing that, #2 should also be fairly straightforward, and may suffice if you can work with the limitation that the WrapPanel will treat the TextBlocks as atoms (ie, it won't wrap intra-TextBlock text).
Approach #3 would allow more flexibility in theory, but it would take some amount of effort and expertise to implement. You also might face some hassles down the road when you might need to adapt your custom panel to new or unforeseen requirements.

WinRt :XAML Tag doesnot exist in the namespace

I am creating a project to which I want to validate textbox ,therefore use prism for that and implementing example like this below
http://msdn.microsoft.com/en-us/library/windows/apps/xx130660.aspx
All I have implemented worked fine but when I changes the code in Page's xaml than it doesn't find the classes etc. which I have implemented .
For Example
<prism:VisualStateAwarePage
xmlns:prism="using:Microsoft.Practices.Prism.StoreApps"
xmlns:vm="using:PrismExample.ViewModels"
xmlns:Behaviors="using:PrismExample.Behaviors"
x:Class="PrismExample.Views.UserInfoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Page.DataContext>
**<vm:UserInfoViewModel/>**
</Page.DataContext>
<TextBox x:Name="FirstNameValue" Grid.Row="2"
Text="{Binding UserInfo.FirstName, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<!--<Behaviors:HighlightFormFieldOnErrors PropertyErrors="{Binding UserInfo.Errors[FirstName]}">-->
**<quickstartBehaviors:HighlightFormFieldOnErrors** PropertyErrors="{Binding UserInfo.Errors[FirstName]}" />
</interactivity:Interaction.Behaviors>
</prism:VisualStateAwarePage>
Now here ,the bold text gives the error that it doesnot exists in the namespace.
Can anybody help me out of this. How I can I get rid of this.
You have:
<Page.DataContext>
**<vm:UserInfoViewModel/>**
</Page.DataContext>
Should this be:
<prism:VisualStateAwarePage.DataContext>
<vm:UserInfoViewModel/>
</prism:VisualStateAwarePage.DataContext>
In your code, you reference quickstartBehaviors but you only have an XMLNS of Behaviors defined in your page. You should look where HighlightFormFieldOnErrors is defined.
Let's pretend that works. But, Noor, I am not sure how to say this. Validation on a control is different than validation in the view model. What I mean is, I think there might be a better way for your to consider. If you are interested, read this: http://blog.jerrynixon.com/2014/07/lets-code-handling-validation-in-your.html
Best of luck!

How can I programmatically launch the toolkit datepicker on windows phone 8

I have this peace of code:
<toolkit:DatePicker x:Name="SchedulerDatePicker"
Grid.Column="1"
Background="White"
Foreground="Black"
BorderThickness="0.5,1,0.5,0.5"
BorderBrush="#77797A"
FontSize="18"
Value="">
</toolkit:DatePicker>
<Button Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Background="Transparent"
BorderThickness="0"
BorderBrush="Transparent"
Click="CalendarButton_Click">
<Image x:Name="ImageDatePicker"
HorizontalAlignment="Right"
Margin="0,0,0,0"
Style="{StaticResource InfoEllipseImage}"
Source="../../Assets/Icons/datepicker.png">
</Image>
</Button>
All this code is inside a .xaml file in a project on Windows Mobile 8. I need to open the DatePicker 'SchedulerDatePicker' inside 'CalendarButton_Click' in code behind. How to do this? I really don't know...
Take a look at point 6 here.
This looks like what you need. Make a subclass of DatePicker as shown in point 6 of that blog post, use your subclass instead of the original DatePicker, and when you want to open it - call the ClickTemplateButton method. Oh, and don't forget to say thanks to the guy who wrote that blog post. :P
For some reason a method to open the picker was not added to the toolkit. You can take a look at its source code somewhere here.
If you are programatically trying to show the DatePickerPage, you could also invoke the private method to do this in the toolkit. Something like this.
typeof(Microsoft.Phone.Controls.DateTimePickerBase).InvokeMember ("OpenPickerPage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, Type.DefaultBinder, this, null);

Accessing named controls from page resources

I needed to access to the ActualWidth of a Border that didn't have a specified Width. I have been told that I can't do that on WinRT so I used a proxy from Florian-Gl (from here).
The thing is that I need to create that proxy on the page's resource like this:
<Page.Resources>
<utils:ActualSizePropertyProxy Element="{Binding ElementName=noteBorder}" x:Name="proxy" />
</Page.Resources>
The problem is that I don't have access to that noteBorder element from the resources, but I have access to pageRoot that is the Page itself.
I guess that I can play with ElementName / Path to get access to noteBorder.
But there is some curious stuff:
The structure is something like:
Page (pageRoot) > Grid > ListView > ListView.ItemTemplate > Grid > Border (noteBorder)
So, If I create the proxy at the same level of the border, It won't run but If I change the ListView to a ItemsControl, it will run and works as expected.
If having it at the same level of the border I change the ElementName to pageRoot it will run at least.
So, It won't run if I put noteBorder (even when I have access to it) if I'm using a ListView, but will work on a ItemsControl, On the other hand, If I have pageRoot it works all ways.
So the question is: Is there a way to access noteBorder from resources? Or maybe a way to access it from another place but working :P
You should be using an Item Template --
By the time you get to
pageRoot) > Grid > ListView or Items Control
At this point in the structure, you're at the element you really want to get at, which is the container of the items that will need the border you are trying to access.
You should define an Item Template and assign the ListView's (or ItemsControl's) ItemTemplate property via binding.
<ListView x:Name="myListView" DataContext="{Binding ToElementIfNotInheritedFromParent}" ItemsSource="{Binding ViewModelListBeingBoundTo}" ItemTemplate="{Binding Source={Static Resource MyCustomItemTemplate}}" />
Where MyCustomItemTemplate is something like
<DataTemplate x:Name="MyCustomItemTemplate">
<Border x:Name="myBorder" >
<StackPanel>
<TextBlock Text="{Binding Path=Title}" />
<TextBlock Text="{Binding Path=FirstProperty}"/>
<TextBlock Text="{Binding Path=SecondProperty}"/>
</StackPanel>
</Border>
</DataTemplate>
Then In your Codebehind (or if ViewModel use the code behind to pass the ListView object to the ViewModel)
DataTemplate dt = this.myListView.Items[indexOfChoice].ItemTemplate as DataTemplate;
Border b = dt.LoadContent() as Border;
int actualWidth = b.AcutalWidth
OR
You can create a FindControl() method that runs recursively to extract the actual control within the border, for instance if you wanted to access one of the Textboxes.
The code for that is here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a612f5a6-e05e-4b68-a813-893eeda159cc