How to fill a StackPanel inside of a UserControl? - xaml

I am creating a custom panel which is basically just a fancier StackPanel with some added functionality. I was going to use a UserControl which contains a StackPanel but I don't know how to make my UserControl accept content to fill it's StackPanel.
This is what I'm trying:
<UserControl
x:Class="transformations.fold_panel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:transformations"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Vertical">
<Button Content="First" />
<ContentControl Content="{x:Bind Content, Mode=OneWay}"></ContentControl>
</StackPanel>
</UserControl>
Usage:
<local:fold_panel>
<Button Content="Second" />
</local:fold_panel>
When I try this I get the following error:
WinRT originate error - 0x80070057 : 'The parameter is incorrect.'.

You can't bind the Content of a StackPanel in a UserControl's Content to the Content property of the same UserControl. This will introduce a circular reference.
In your example, the Content property of the fold_panel UserControl will be set to the StackPanel that you defined in the XAML markup.
If you want to be able to set the Content of the ContentControl in the StackPanel, you should add a custom dependency property to the fold_panel class and bind the Content property of the ContentControl to this one:
<ContentControl Content="{x:Bind CustomContent, Mode=OneWay}" />
You can then set your custom property something like this:
<local:fold_panel>
<local:fold_panel.CustomContent>
<Button Content="Second" />
<local:fold_panel.CustomContent>
</local:fold_panel>
But if you really want a custom StackPanel, you should create a class that inherits from StackPanel rather than UserControl.

Related

binding tooltip to custom dependency property

this code work correct:
<UserControl x:Class="Extended.InputControls.TextBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Extended.InputControls">
<TextBox x:Name="textBox"
ToolTip="{Binding Path=CustomToolTip,RelativeSource={RelativeSource AncestorType=local:TextBoxUserControl}}"/>
</UserControl>
but this code Does not work!!!
<UserControl x:Class="Extended.InputControls.TextBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Extended.InputControls">
<TextBox x:Name="textBox">
<TextBox.ToolTip>
<ToolTip Text="{Binding Path=CustomToolTip,RelativeSource={RelativeSource AncestorType=local:TextBoxUserControl}}" Background="Yellow"/>
</TextBox.ToolTip>
</TextBox>
</UserControl>
i need create custom tooltip and bind it to CustomToolTip but in second code that's not bind to anything
where is the problem?
First of all, if we're talking WPF here, it should be <ToolTip Content="..."> instead of <ToolTip Text="...">, since ToolTip has no Text property.
Regarding the binding: Binding to other elements in the user control from within a ToolTip doesn't work since ToolTip elements are not part of the visual tree, as explained in another question that also provides one potential solution.
However, it seems that you're binding to some property defined in the UserControl's code-behind? In that case it's even easier to solve by setting the UserControl's DataContext to the control itself:
<UserControl x:Class="Extended.InputControls.TextBoxUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Extended.InputControls"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<TextBox x:Name="textBox">
<TextBox.ToolTip>
<ToolTip Content="{Binding CustomToolTip}" Background="Yellow"/>
</TextBox.ToolTip>
</TextBox>
</UserControl>
Alternatively, you could also set the DataContext in code-behind:
public TextBoxUserControl()
{
this.DataContext = this;
InitializeComponent();
}
In both cases, the CustomToolTip property can be accessed directly without the need for a RelativeSource binding.
An even better solution would be to introduce come kind of Viewmodel class that holds the CustomToolTip and all similar properties, and set this class as the UserControl's DataContext.

Prevent Page Expanding Frame in Windows 8 XAML App within ScrollView

I'm creating a basic application to test some functionality in a XAML based Windows 8 app.
I have created the following structure to simplify my example but in the real app it'll be more complex:
<Page
x:Name="pageRoot"
x:Class="ScrollingTest.Xaml.MainPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ScrollingTest.Xaml"
xmlns:common="using:ScrollingTest.Xaml.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer
HorizontalScrollMode="Auto"
HorizontalScrollBarVisibility="Auto"
VerticalScrollMode="Disabled"
VerticalScrollBarVisibility="Hidden" Margin="0,0,0,10" VerticalContentAlignment="Stretch" BorderBrush="#FF0BC8FF" BorderThickness="1" Grid.Row="1" >
<Frame Content="Frame" Name="theFrame" Margin="100" Width="3000" BorderBrush="Red" BorderThickness="1"
ScrollViewer.VerticalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Visible" />
</ScrollViewer>
</Grid>
</Page>
The page, which is loaded into the Frame is of variable height (it contains a listview).
The issue is that as the height of the sub-page increases, so does the height of the ScrollViewer, meaning that the content is forced off the bottom of the screen.
What I'd want to achieve is horizontal scrolling for the parent but then use vertical scrolling on the sub-page. In the real application there will be many sub-pages, probably within a grid.
It seems that putting the frame inside a ScrollViewer breaks the frame's internal scrolling capabilities.
If anyone could let me know of either a better way to achieve my end result or of some property I need to change then I'd be very grateful.
I ended up using the solution from the following comment:
XAML: Limiting size of control nested in ScrollViewer (to scroll nested within the ScrollViewer)
Height="{Binding ElementName=scrollViewer, Path=ActualHeight}"
Not really what I wanted as this doesn't cope automatically when changing the orientation but it will have to do.
The other option is to handle the SizeChanged event of the page and update the height from the event handler (theFrame.Height = scrollViewer.ActualHeight). That way it copes with changing the orientation as well.

Load a Page into a ContentControl

I have a ContentControl where I want to load the page myPage2. My XAML Codefrom this page looks like this:
<Page x:Class="ExampleApp.myPage2">
<Grid x:Name="Content" Height="651" Width="941" Background="White">
...
...
</Grid>
</Page>
I know that I can load a resource from a page with this Code:
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var contentControl = (ContentControl)container;
return (DataTemplate) contentControl.Resources[templateKey];
}
My problem now is that I can't load a page like above with this code. I have to write this:
<Page x:Class="ExampleApp.myPage2">
<Page.Resources>
<DataTemplate x:Key="Test">
<Grid x:Name="Content" Height="651" Width="941" Background="White">
...
...
</Grid>
</DataTemplate>
</Page.Resources>
</Page>
And then I can load the page with the same Code from above with templateKey="Test". But the main problem is that I want to use the first declaration of the page and do not want to use <Page.Resources> <DataTemplate x:Key="Test"> and so on. I want to load the site direcly from the first declaration (first code in this post). How can I create a DataTemplate directly from a page? Or is there an other way to load a page into a ContentControl?
There is no reason to use a Page within a ContentControl. A Page is a subclass of the UserControl class that adds support for being used within a Frame control to support navigation, back stack/history, etc. You should probably replace Page with UserControl in XAML and code behind, so you would end up with something like this:
<UserControl x:Class="ExampleApp.myControl2">
<Grid x:Name="Content" Height="651" Width="941" Background="White">
...
...
</Grid>
</UserControl>
You can put the UserControl itself in a DataTemplate if you want to use it as a DataTemplate in a ContentControl:
<ContentControl
xmlns:controls="using:ExampleApp">
<ContentControl.Resources>
<DataTemplate
x:Key="Test">
<controls:myControl2 />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>

How to remove EntranceThemeTransition from a single object in a Windows 8 App?

It seems like every object that has been added to a page in a Windows 8 App gets this "slide from right to left"-entrance-transition which begins whenever someone navigates to the page.
Is there a possibility to remove single objects from this transition?
Neither
<Object.Transitions>
<TransitionCollection />
</Object.Transitions>
nor this thread helped...
Any ideas?
AFAIK There's no way to exempt a given object from the transitions applied by it's parents. The only thing I can suggest is to structure your xaml in such a way that the transition isn't applied. By this I mean having this special item in a panel that has no children transitions while the rest of the page is in a panel with a child transition. Depending on where this item is it could be very easy or difficult as hell.
As Nigel suggested, the only solution I have found has been to change the page structure and put the elements out of the grid that has the animations:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.Transitions>
<TransitionCollection/>
<!-- Ensure no transitions in background -->
</Grid.Transitions>
<TextBlock FontSize="50" Margin="50">This item is not animated</TextBlock>
<Grid>
<Grid.ChildrenTransitions>
<TransitionCollection>
<!-- add transitions here -->
<EntranceThemeTransition FromVerticalOffset="1500" FromHorizontalOffset="1500"/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<TextBlock Margin="50,100" FontSize="50">This item is animated</TextBlock>
</Grid>
<TextBlock FontSize="50" Margin="50,150">Another not animated item</TextBlock>
</Grid>
</Page>

Control Inheritance with Blend in Silverlight 3

i would like to create a custom base class for some of my UserControls.
Doing this in VS2008 is fine and compiles as expected, but when i edit the control in Blend 3 the base class in the blabla.g.vb is always changed back to System.Windows.Controls.UserControl.
How can i force Blend to keep the assigned base class?
regards
Christoph
Can you show your XAML?
I suspect the case is your XAML is like this:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication15"
x:Class="SilverlightApplication15.MainPage"
Width="640"
Height="480">
<Grid x:Name="LayoutRoot"
Background="#FF313131" />
</UserControl>
When it should be something like:
<local:BlahBlah xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication15"
x:Class="SilverlightApplication15.MainPage"
Width="640"
Height="480">
<Grid x:Name="LayoutRoot"
Background="#FF313131" />
</local:BlahBlah>
The .g.vb file is generated from the XAML so it's not a file you should edit directly.