Different method of switching pages hub class in VS C# Windows Universal - c#

So, this may seem rather basic, but so far, the only method I've found in C# for switching the current page in windows universal app is to use the header clicked method combined with setting the IsHeaderInteractive to true. this doesn't look or feel very intuitive considering it just sticks in the little "see more" button that you click on. Rather, how would I go about adding a click event to the entire hub section that changes the page. Here's what I have right now.
private void HubSection_Click(object sender, HubSectionHeaderClickEventArgs e)
{
switch (e.Section.Name)
{
case "China":
Frame.Navigate(typeof(SubtopicPage));
break;
case "Japan":
Frame.Navigate(typeof(SubtopicPage));
break;
}
}
here's the XAML as well:
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource SystemControlForegroundBaseHighBrush}">
<Hub Header="Countries App" Foreground="#FFC3BFBF" SectionHeaderClick="HubSection_Click" Name="CountryHub">
<HubSection x:Name="China" MinWidth="256" Height="460" Background="#FF343434" Header="China" IsHeaderInteractive="True">
<DataTemplate>
<Grid Height="460" Width="256" VerticalAlignment="Bottom">
<Image Source="Assets/chinaFlag.bmp"/>
</Grid>
</DataTemplate>
</HubSection>
<HubSection x:Name ="Japan" MinWidth="256" Height="460" Background="#FF565454" Header="Japan" IsHeaderInteractive="True">
<DataTemplate>
<Grid Height="460" Width="256" VerticalAlignment="Bottom">
<Image Source="Assets/japanFlag.bmp" Height="169"/>
</Grid>
</DataTemplate>
</HubSection>
<HubSection Width="256" Height="460" Background="#FF343434">
</HubSection>
<HubSection Width="256" Height="460" Background="#FF565454">
<DataTemplate>
<Grid Height="460" Width="256" VerticalAlignment="Bottom"/>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
currently two of the four hub sections don't have content, but that's beside the point. Thanks for the help in advance.

Agree with RicardoPons, as I known there is no method to get selected item.
As a work round, You can add Tabbed event of the HubSection. You can know which HubSection was tapped.
For example:
<Hub Header="Countries App" Foreground="#FFC3BFBF" SectionHeaderClick="HubSection_Click" Name="CountryHub">
<HubSection x:Name="China" MinWidth="256" Height="460" Background="#FF343434" Header="China" IsHeaderInteractive="True" Tapped="{x:Bind HubSectionTapped}">
<DataTemplate>
<Grid Height="460" Width="256" VerticalAlignment="Bottom">
<Image Source="Assets/dog.jpg" />
</Grid>
</DataTemplate>
</HubSection>
<HubSection x:Name ="Japan" MinWidth="256" Height="460" Background="#FF565454" Header="Japan" IsHeaderInteractive="True" Tapped="{x:Bind HubSectionTapped}">
<DataTemplate>
<Grid Height="460" Width="256" VerticalAlignment="Bottom">
<Image Source="Assets/color.jpg" Height="169" />
</Grid>
</DataTemplate>
</HubSection>
</Hub>
In code behind:
private void HubSectionTapped(object sender, TappedRoutedEventArgs e)
{
var hubSectiona = sender as HubSection;
var name = hubSectiona.Name;
NaviagteMethod(name);
}
public void NaviagteMethod(string name)
{
switch (name)
{
case "China":
Frame.Navigate(typeof(SubtopicPage));
break;
case "Japan":
Frame.Navigate(typeof(SubtopicPage));
break;
}
}

I think for now it is the only way.
I read the official article in MSDN documentation it seems there is not an event or property to get the current selected item.
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.controls.hub.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

Related

Responsive Windows App Element

Is there any XAML element that will automatically wrap to a new line for sub elements that don't have enough room on a line?
What I mean is that on a wide screen I'll get:
Box1 Box2 Box3
And on a narrow one:
Box1 Box2
Box3
Without having to listen to events and fix it by code.
The comments mention VariableSizedWrapGrid as a solution. But I can't figure out how to make it wrap.
You can use a simple GridView to do it. If you don't set a Height, it should work like a charm.
<GridView Name="xConcerts" ItemsSource="{x:Bind Artist.UpcomingEvents, Mode=OneWay}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="songkick:EventExt">
<Border CornerRadius="8" Background="{ThemeResource ThemeGrayHighColorBrush}" Opacity="0.8">
<StackPanel Margin="18,2">
<TextBlock Text="{x:Bind FullDisplayDate, Converter={StaticResource FormatStringToDateDayConverter}}" Style="{ThemeResource ThemeDateBoldStyle}"/>
<TextBlock Text="{x:Bind FullDisplayDate, Converter={StaticResource FormatStringToDateMonthConverter}}" Style="{ThemeResource ThemeDateBoldStyle}" Margin="0,-4,0,0"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerTransitions>
<TransitionCollection>
<RepositionThemeTransition/>
</TransitionCollection>
</GridView.ItemContainerTransitions>
</GridView>
According to your requirement, using the WrapPanel control in WinRTXamlToolkit will meet your needs.
Sample code here:
<Page x:Class="TestDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Tool="using:WinRTXamlToolkit.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TestDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Tool:WrapPanel>
<Button Width="200" Margin="10">1</Button>
<Button Width="200" Margin="10">2</Button>
<Button Width="200" Margin="10">3</Button>
</Tool:WrapPanel>
</Page>
And the output here:

UWP CommandBar - Content is completely separate context?

I've been trying to implement Microsoft's hamburger pattern in my own way for some time.
Final result was the following:
AppShell for containing current page and hamburger menu (menu always visible)
In Appshell, Grid with two rows: one 48px in height, one one-start height.
In first row, added a commandbar (global), and hamburger button (togglebutton with custom style for being 48px wide and tall, with the hamburger fonticon in the center)
In second row, SplitView with a ListBox on the Pane, and a Frame in the Content.
This way one has control over the content, while displaying a global menu and command bar. On the Navigated event of the Frame, I update the CommandBar to pull the primary and secondary commands from the Frame's Content's properties (I use a custom page control with those properties), and the content of the CommandBar (which is, of now, a single TextBlock with binding).
However, I wanted to move the ToggleButton into the CommandBar. It worked nicely, except the binding (IsChecked of ToggleButton is bound to IsPaneOpen of SplitView) does not work. I use the regular ElementName targeting, and would prefer to not to use a ViewModel property.
Does the CommandBar.Content use a different context? Or why doesn't the ElementName reference work?
Only way, how I was able to bind to AppBarToggleButton was to set the DataContext in the code behind.
XAML:
<Page.BottomAppBar>
<CommandBar x:Name="CommandBar">
<AppBarToggleButton x:Name="Button" IsChecked="{Binding IsPaneOpen, Mode=TwoWay}" Icon="Home" Label="Button"/>
</CommandBar>
</Page.BottomAppBar>
Code behind:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
Button.DataContext = SplitView;
}
This works for me:
<Page
x:Class="StackOverflowTests.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CommandBar>
<CommandBar.Content>
<AppBarToggleButton Icon="Globe" IsChecked="{Binding ElementName=SplitView,Path=IsPaneOpen,Mode=TwoWay}"/>
</CommandBar.Content>
</CommandBar>
<SplitView Grid.Row="1" Name="SplitView" IsPaneOpen="{x:Bind Appbarbutton.IsChecked.Value,Mode=OneWay}">
<SplitView.Pane>
<ListBox>
<ListBoxItem>Foo</ListBoxItem>
<ListBoxItem>Bar</ListBoxItem>
</ListBox>
</SplitView.Pane>
<SplitView.Content>
<TextBlock>stuff here</TextBlock>
</SplitView.Content>
</SplitView>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<CommandBar.Content>
<AppBarToggleButton Name="Appbarbutton" Icon="Home" />
</CommandBar.Content>
</CommandBar>
</Page.BottomAppBar>
</Page>
You have bind DataContext:
Example:
<Page.BottomAppBar >
<CommandBar x:Name="commandBar" DataContext="{Binding}">
<CommandBar.Content>
<StackPanel Margin="0,0">
<ListView ItemsSource="{Binding Confirmation.AvailableValues}" ItemContainerStyle="{StaticResource ListViewItemBase}">
<ListView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Value.DisplayName}" Command="{Binding DataContext.Confirm, ElementName=commandBar}" CommandParameter="{Binding Value}" HorizontalAlignment="Center"></Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Line Margin="5" X1="0" X2="1000" Y1="0" Y2="0" HorizontalAlignment="Stretch" Height="2" Stroke="#888888" StrokeThickness="1" ></Line>
</StackPanel>
</CommandBar.Content>
</CommandBar>
</Page.BottomAppBar>

Flow icon view in WPF ListView

I am new to WPF and as a learning project I opted for a Windows Explorer like File Manager. In this project I want to display the the List view as a icon list that follows flow layout pattern. I tried the solutions given here: WPF: ListView with icons view?. But they are making my icons overlap each other. My icons are basically user controls that are loaded dynamically. This is my code for user control that represents a list view icon:
<UserControl x:Class="MVCP.FileItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="156.767" Width="161.279">
<Grid HorizontalAlignment="Center">
<Image HorizontalAlignment="Center" Height="100" Margin="10,10,10,0" VerticalAlignment="Top" Width="141" Source="fileflat.png"/>
<TextBlock HorizontalAlignment="Center" Margin="10,120,10,5" TextWrapping="Wrap" Text="<Filename>" VerticalAlignment="Center" Height="32" Width="141" FontSize="18" Foreground="White" TextAlignment="Center"/>
</Grid>
</UserControl>
And this is my ListView code:
<ListView x:Name="files" Background="#FF19174B" AllowDrop="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" PreviewMouseLeftButtonDown="files_PreviewMouseLeftButtonDown" MouseMove="files_MouseMove">
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
</ListView>
How can I arrange these user controls so that they can look like Windows Explorer icons?
#AbinMathew gave me a hint for using Panels. So, I changed my code like this and it worked. :)
<ListView x:Name="files" Background="#FF19174B" AllowDrop="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" PreviewMouseLeftButtonDown="files_PreviewMouseLeftButtonDown" MouseMove="files_MouseMove">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<local:FileItem/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
</ListView>
Try adding any panel inside your ListView
<ListView x:Name="files" Background="#FF19174B" AllowDrop="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled" PreviewMouseLeftButtonDown="files_PreviewMouseLeftButtonDown" MouseMove="files_MouseMove">
<StackPanel>
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
<local:FileItem/>
</StackPanel>
</ListView>

Adding custom class with XAML in ListBox C# WPF

I have a class PC that contains Image, Label (with XAML design) and I want to get a list of PCs in ListBox in other class.
I tried this, but I get error System.Windows.Markup.XamlParseException:
pc p = new pc();
list_pc.Items.Add(p);
(where list_pc is a ListBox)
This is the XAML for a single PC:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="TnCyberCafe.pc"
Title="pc"
SizeToContent="WidthAndHeight"
ShowInTaskbar="False"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
AllowsTransparency="True"
Background="Transparent" Width="95" Height="104.982">
<Grid HorizontalAlignment="Left" Margin="0,10,-15,10" Width="110">
<Image x:Name="image" HorizontalAlignment="Left" Height="96" VerticalAlignment="Top" Width="100" Source="Resources/aaa.png" RenderTransformOrigin="0.5,0.26" Margin="0,-16,0,0"/>
<Label Content="Label" HorizontalAlignment="Left" Height="25" Margin="20,70,0,-10" VerticalAlignment="Top" Width="45"/>
</Grid>
</Window>
This is the XAML for my list_pc:
<ListBox x:Name="liste_pc" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
List PCs
</ListBox>
Your first question regarding the System.Windows.Markup.XamlParseException:
As Garry Vass mentioned something went wrong, but does not tell you exactly what happened. If you are developing in Visual Studio, Click on Exceptions under Debug Tab and enable Common Language Runtime Exceptions. This will point you to the Error Code.
For the second question you should have databindings and ListBox Itemtemplate as below
<ListBox x:Name="liste_pc" ItemsSource="{Binding PCList}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding PCImageSource}" />
<Label Content="{Binding Path=PCName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
where PCList is the observable collection of PC Class object items

Caliburn Micro: UserControl Binding

I use Caliburn Micro for my WPF application. I implemented a little UserControl:
<UserControl Name="ImageButtonUserControl"
x:Class="SportyMate.Utility.Controls.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid>
<Button>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ElementName=ImageButtonUserControl, Path=Image}" />
<TextBlock Text="{Binding ElementName=ImageButtonUserControl, Path=Text}" />
</StackPanel>
</Button>
</Grid>
</UserControl>
Now I want to use these Control in my view:
<uc:ImageButton Name="Cancel" Image="/Images/Icons/cancel_16x16.png" Text="Abbrechen" Margin="3" />
When I want to open my view (in my case it's opened as a dialog) it doesn't work. The View does not openend.
When I remove the Name-Attribute everthing is fine, but the Button have no binding to an action. Can anyone tell me what I have to do for a correct binding? A regular Button worked.
You are on a completely wrong way. You shouldn't create a user control for such a simple modification. You need to create a DataTemplate and use it for a Button.ContentTemplate. First you need to define a helper type for button content:
public class ImageButtonContent
{
public BitmapImage Image { get; set; }
public string Label { get; set; }
}
After that you can use it for DataTemplate:
<Window x:Class="Trys.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Trys="clr-namespace:Trys"
Title="MainWindow"
Height="350"
Width="525">
<Window.Resources>
<Trys:ImageButtonContent x:Key="YourImageButtonHere"
Label="Your ImageButtonHere">
<Trys:ImageButtonContent.Image>
<BitmapImage UriSource="your-icon.png" />
</Trys:ImageButtonContent.Image>
</Trys:ImageButtonContent>
<DataTemplate x:Key="ImageButton"
DataType="{x:Type Trys:ImageButtonContent}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}"
Margin="5" />
<TextBlock Text="{Binding Label}"
VerticalAlignment="Center"
Margin="10,0,0,0" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Button ContentTemplate="{StaticResource ImageButton}"
Content="{StaticResource YourImageButtonHere}"
Height="50"
Width="250" />
</Grid>
</Window>
I used a resource for an object, but you can use a property on your ViewModel. The result is:
And this just a normal button. You can use for it all power of Caliburn.Micro conventions like Click event default binding. Enjoy!

Categories

Resources