How to use icon in mahapps hamburger menu XAML - wpf

How do I use Entypo icon in mahapps hamburger menu?
I've tried many ways but nothing works. Below is my xaml code:
<controls:HamburgerMenu.ItemsSource>
<controls:HamburgerMenuItemCollection>
<controls:HamburgerMenuIconItem Icon="{iconPacks:PackIconEntypo Kind=Users}" Label="Accounts">
<controls:HamburgerMenuIconItem.Tag>
<views:AccountsView/>
</controls:HamburgerMenuIconItem.Tag>
</controls:HamburgerMenuIconItem>
</controls:HamburgerMenuItemCollection>
</controls:HamburgerMenu.ItemsSource>

You need to define a datatemplate :
<DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type controls:HamburgerMenuIconItem}">
<Grid Height="64">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="64" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Viewbox ToolTip="{Binding Label}" Width="32" Height="32" >
<Viewbox.Child>
<ContentControl Content="{Binding Path=Icon}"></ContentControl>
</Viewbox.Child>
</Viewbox>
</Grid>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
Then apply this datatemplate setting this property in your HamburgerMenu
ItemTemplate="{StaticResource MenuItemTemplate}"
Please mind that the widths and heights defined in the datatemplate can be modified to fit your menĂ¹ size. You can define your own datatemplate, but you need to tell your application where how to display the Icon

Here is a full example with DataTemplate & ItemSource:
<mah:HamburgerMenu
ItemTemplate="{StaticResource MenuItemTemplate}"
OptionsItemTemplate="{StaticResource MenuItemTemplate}">
<!-- Content -->
<mah:HamburgerMenu.ContentTemplate>
<DataTemplate DataType="{x:Type mah:HamburgerMenuItem}">
<Grid>
<ContentControl
Content="{Binding Tag}"
Focusable="False"
Foreground="Black" />
</Grid>
</DataTemplate>
</mah:HamburgerMenu.ContentTemplate>
<!-- Options -->
<mah:HamburgerMenu.OptionsItemsSource>
<mah:HamburgerMenuItemCollection>
<mah:HamburgerMenuIconItem Label="Option 1">
<mah:HamburgerMenuIconItem.Icon>
<iconPacks:PackIconMaterial Kind="EmoticonCool" VerticalAlignment="Center" HorizontalAlignment="Center" />
</mah:HamburgerMenuIconItem.Icon>
<mah:HamburgerMenuIconItem.Tag>
<TextBlock>Option 1</TextBlockl>
</mah:HamburgerMenuIconItem.Tag>
</mah:HamburgerMenuIconItem>
</mah:HamburgerMenuItemCollection>
</mah:HamburgerMenu.OptionsItemsSource>
<!-- Items -->
<mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenuItemCollection>
<mah:HamburgerMenuIconItem Label="Item 1">
<mah:HamburgerMenuIconItem.Icon>
<iconPacks:PackIconMaterial Kind="EmoticonCool" VerticalAlignment="Center" HorizontalAlignment="Center" />
</mah:HamburgerMenuIconItem.Icon>
<mah:HamburgerMenuIconItem.Tag>
<TextBlock>Item 1</TextBlockl>
</mah:HamburgerMenuIconItem.Tag>
</mah:HamburgerMenuIconItem>
</mah:HamburgerMenuItemCollection>
</mah:HamburgerMenu.ItemsSource>
</mah:HamburgerMenu>

Related

How to center UserControl in a TabControl

My MainWindow is built with TabContol containing in each tab UserControl in xaml files. Opening specific UserControl is not a problem, but aligning it is. I was able to horizontally center content of tab but struggle to vertically do this same. I found out that the root problem is that UserControl don't take the whole free space (height) in the Tab. I tried to make main grid VerticalAlignment="Stretch" and "Center" but that didn't help. I could use margin with specific number or define row fixed hight but that will not work on every resolution and I don't want to write method in code behind but use the power of xaml. How can I force UserControl to take whole height in Tab and then vertically center it (it's important to do it for specific UserControl because others should have default position)?
ps. I'm using MetroWindow from MahApps.Metro.
MainWindow main Grid:
<Grid>
<StackPanel>
<TabControl ItemsSource="{Binding Tabs}"
SelectedIndex="0">
<TabControl.Resources>
<Style TargetType="{x:Type TabPanel}">
<Setter Property="HorizontalAlignment"
Value="Center" />
</Style>
<DataTemplate DataType="{x:Type VMod:LoginViewModel}">
<Pages:LoginView />
</DataTemplate>
<DataTemplate DataType="{x:Type VMod:AdminViewModel}">
<Pages:AdminView />
</DataTemplate>
<DataTemplate DataType="{x:Type VMod:ProductsViewModel}">
<Pages:ProductsView />
</DataTemplate>
<DataTemplate DataType="{x:Type VMod:DistributionViewModel}">
<Pages:DistributionView />
</DataTemplate>
<DataTemplate DataType="{x:Type VMod:SummaryViewModel}">
<Pages:SummaryView />
</DataTemplate>
<DataTemplate DataType="{x:Type VMod:SettingsViewModel}">
<Pages:SettingsView />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemTemplate>
<DataTemplate DataType="{x:Type inter:ITab}">
<TextBlock>
<Run Text="{Binding TabName}" />
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</StackPanel>
</Grid>
UserControl main Grid:
<Grid Background="LightBlue"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Height="300"
Width="300"
Grid.Row="2"
BorderBrush="LightGray"
BorderThickness="1">
<StackPanel HorizontalAlignment="Center">
<iconPacks:PackIconRPGAwesome Kind="Honeycomb"
HorizontalAlignment="Center"
Width="60"
Height="60"
Margin="0, 0, 0, 0"/>
<TextBlock HorizontalAlignment="Center"
Text="DistributionTool"
FontSize="20"
FontWeight="Bold"
Margin="5" />
<Grid Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Margin="5"
TextAlignment="Left"
FontSize="15"/>
<iconPacks:PackIconMaterial Grid.Column="1"
Kind="AccountTie"
Width="20"
Height="20"
VerticalAlignment="Center"/>
</Grid>
<Grid Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<PasswordBox Grid.Column="0"
Margin="5"
HorizontalContentAlignment="Left"
FontSize="15"
Style="{StaticResource Win8MetroPasswordBox}" />
<iconPacks:PackIconMaterial Grid.Column="1"
Kind="Key"
Width="20"
Height="20"
VerticalAlignment="Center" />
</Grid>
<Button Content="LOGIN"
Width="80"
metro:ControlsHelper.ContentCharacterCasing="Normal"
Margin="5"
Style="{StaticResource AccentedSquareButtonStyle}" />
</StackPanel>
</Border>
</Grid>
From what I gather, what you could try would be:
Remove the StackPanel in your MainWindow Grid. Unless you intend to have more than 1 child inside the stack panel (Other than your TabControl), it is useless.
Add VerticalAlignement="Stretch" to your TabControl. This will allow it to take up all the space it can vertically.
Then you should be pretty much set to go.
The reason why you shouldn't use a StackPanel unless you intend to stack items inside, as in
<StackPanel>
<Child1/>
<Child2/>
</StackPanel>
is that the StackPanel.Orientation property affects how things will appear inside, including the Alignement of each child.
So Orientation="Vertical" (the default), affects the VerticalAlignement of its children. Same idea with Horizontal.

Designing a Hamburger menu in WPF with Mahapps.Metro

Currently, I'm using a Grid of Buttons for housing keys for navigation. It's hideous, but gets the job done.
Here's the XAML chunk:
<Button x:Name="ShowMainMenu" Grid.Column="0" Margin="5" Content="Main Menu"/>
<Button x:Name="ShowReportsMenu" Grid.Column="2" Margin="5" Content="Reports"/>
<Button x:Name="Reset" Grid.Column="4" Margin="5" Content="Reset"/>
<Button x:Name="TryClose" Grid.Column="6" Margin="5" Content="Close"/>
Incidentally, I'm using Caliburn.micro, and so naming the buttons is enough to bind them to proper commands.
Now, I want them to put them in a Hamburger Menu.
What I have tried till now is this:
<Controls:HamburgerMenu >
<Controls:HamburgerMenu.ItemTemplate>
<DataTemplate DataType="{x:Type Controls:HamburgerMenuGlyphItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Margin="12" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Glyph}" />
<TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Text="{Binding Label}" />
</Grid>
</DataTemplate>
</Controls:HamburgerMenu.ItemTemplate>
<Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuGlyphItem Glyph="1" Label="Main Menu" cal:Message.Attach="[Event Click] = [Action ShowMainMenu]"/>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.ItemsSource>
</Controls:HamburgerMenu>
But it doesn't work, because Controls:HamburgerMenuGlyphItem isn't a FrameworkElement.
By the way, the transitioning view is implemented like this:
So, how can I translate my bunch of Buttons into a HamburgerMenu? I can't find proper documentation for Caliburn.micro's HamburgerMenu as well.
Well, I figured it out myself.
Here's the code:
<DockPanel>
<DockPanel.Resources>
<DataTemplate x:Key="MenuItemTemplate">
<Grid Height="48" Background="Black">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<cal:ActionMessage MethodName="{Binding Tag}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Segoe MDL2 Assets" Foreground="BlanchedAlmond" Text="{Binding Glyph}"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" FontSize="16" Foreground="White" Text="{Binding Label}"/>
</Grid>
</DataTemplate>
</DockPanel.Resources>
<Controls:HamburgerMenu Foreground="White" PaneBackground="#FF444444" IsPaneOpen="False" DisplayMode="CompactOverlay" OptionsItemTemplate="{StaticResource MenuItemTemplate}" ItemTemplate="{StaticResource MenuItemTemplate}">
<Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuGlyphItem Glyph="M" Label="Main Menu" Tag="ShowMainMenu"/>
<Controls:HamburgerMenuGlyphItem Glyph="I" Label="Invoice" Tag="OpenInvoiceMaker"/>
<Controls:HamburgerMenuGlyphItem Glyph="R" Label="Reports" Tag="ShowReportsMenu"/>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.ItemsSource>
<Controls:HamburgerMenu.OptionsItemsSource>
<Controls:HamburgerMenuItemCollection>
<Controls:HamburgerMenuGlyphItem Glyph="A" Label="About" Tag="About"/>
</Controls:HamburgerMenuItemCollection>
</Controls:HamburgerMenu.OptionsItemsSource>
<Controls:HamburgerMenu.Content>
<DockPanel>
<Border Background="#FF444444" DockPanel.Dock="Top">
<TextBlock x:Name="Header" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15" Foreground="White" Text="{Binding ActiveItem.DisplayName}" />
</Border>
<ScrollViewer Grid.Row="1" CanContentScroll="True" IsDeferredScrollingEnabled="False">
<Controls:TransitioningContentControl Transition="LeftReplace" x:Name="ActiveItem" Content="{Binding ActiveItem}"/>
</ScrollViewer>
</DockPanel>
</Controls:HamburgerMenu.Content>
</Controls:HamburgerMenu>
</DockPanel>
Basically, I used EventTrigger to achieve the same functionality as a button. The rest was easy.

textblock in user control TextWrapping not wrapping

I created user control with the textblock. But it will not wrap. This user control servers as a listboxitem.
<Grid x:Name="MainGrid" Height="Auto" Width="Auto">
<StackPanel Orientation="Horizontal">
<Image Height="50" Width="100" Stretch="Uniform" Name="image1" Source="{Binding Path=VideoImageUrl}" Margin="12,12,13,84" MouseLeftButtonDown="image1_MouseLeftButtonDown" MouseEnter="image1_MouseEnter" MouseLeave="image1_MouseLeave" />
<StackPanel Orientation="Vertical" >
<TextBlock TextWrapping="Wrap" Height="Auto" HorizontalAlignment="Left" Name="titleTextBox"
Text="{Binding Path=Title, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}"
VerticalAlignment="Center" Width="Auto" FontSize="14" FontWeight="SemiBold" />
<StackPanel Orientation="Vertical" x:Name="StackPanelDetails">
<TextBlock Height="Auto" HorizontalAlignment="Left" Name="desciptionTextBox"
TextWrapping="Wrap"
Text="{Binding Path=Desciption, Mode=OneWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}"
VerticalAlignment="Center" Width="Auto" />
<Line />
<ItemsControl x:Name="CustomItemsSource" ItemsSource="{Binding Path=LinksList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink NavigateUri="{Binding Path=TopicUrl}" RequestNavigate="Hyperlink_RequestNavigate" >
<TextBlock Text="{Binding Path=TopicName}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
A ListBox's default template does not automatically limit the width of its items, but instead uses a ScrollViewer, which shows a horizontal scrollbar when an item is wider than the ListBox.
You can remove the ScrollViewer by replacing the ListBox's Template:
<ListBox ...>
<ListBox.Template>
<ControlTemplate>
<StackPanel IsItemsHost="True"/>
</ControlTemplate>
</ListBox.Template>
...
</ListBox>
Another important thing to note is that a StackPanel in the top-level Grid won't properly resize the contained elements. In the following simplified example the text in the TextBlock is not wrapped because the containing StackPanel simply does not resize it as you expect:
<Grid>
<StackPanel Orientation="Horizontal">
<Image ... />
<Text TextWrapping="Wrap" Text=... />
</StackPanel>
</Grid>
This way it works as you expect:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image ... />
<TextBlock Grid.Column="1" TextWrapping="Wrap" Text=... />
</Grid>

How to show a divider between items in a ListBox?

I am using a ListBox control in a Windows Phone 7 application, and I would like to show a divider/line between the list rows.
I have not been able to find any information about this, although many (not wp7) ListBox examples seem to have a divider.
Got inspired by NestorArturo and found out about the Border control.
It is very easy to wrap your ItemTemplate content in a Border control and specify the BorderThickness and BorderBrush. I went this way, because it doesn't require changes to my Grid in the ItemTemplate.
The Border control is described here: http://www.silverlightshow.net/items/Using-the-Border-control-in-Silverlight-2-Beta-1-.aspx.
Below you can see how I use it:
<ListBox Background="White" ItemsSource="{Binding Mode=OneWay, Path=MyPath}" Name="listName" SelectionChanged="listName_SelectionChanged">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
here --> <Border BorderThickness="0,10,0,10" BorderBrush="Black">
<Grid Width="auto" HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" FontSize="36" FontWeight="Bold" Grid.Column="0" Foreground="Black" Text="{Binding Path=Title}" Name="title"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Column="1" Foreground="Black" Text="{Binding Path=Location}" Name="location"/>
<Image VerticalAlignment="Center" Grid.Column="2" Width="48" Height="48" Source="ApplicationIcon.jpg"/>
</Grid>
and here --> </Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can either change the ListBoxItem template, or, an easier approach is to change your ItemTemplate, You can simply add a divider within your ItemTemplate as follows:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<!-- your content goes here ... for example: -->
<TextBlock Text={Binding Path=InterestingThing}"/>
<!-- the divider -->
<Line X1="0" X2="200" Y1="0" Y2="0"
VerticalAlignment="Bottom"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>

Wpf Bind View to ViewModel add to wpf window

I have a view that contains a ItemsControl with some textblocks inside to display the name and other information. in my window I am adding the view to the window as follows and in the code behind of the window i am binding the datacontext of the view to the view model in the MainWindow Loaded event as follows ViewOwnerSideBar.DataContext = viewModel The application compiles but when I run it I dont get data? I checked my viewmodel and I do have data in my collection that I am returning. Does anyone have any good examples of how to do this. I am going to have a sidebar view and a main view on the right displaying the details of the owner.
This is my View
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/ColorsAndBrushes.xaml"/>
<ResourceDictionary Source="/Resources/DefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DockPanel >
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<ItemsControl Width="250"
VerticalAlignment="Stretch"
BorderThickness="0"
ItemsSource="{Binding Path=AllOwners}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="2">
<Border Margin="2 2 0 0"
CornerRadius="4"
Background="Gray"
Opacity=".5" />
<Border BorderBrush="{StaticResource redBrush}"
BorderThickness="2"
CornerRadius="4"
Background="White"
Margin="0 0 2 2"
Padding="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.ColumnSpan="2"
FontWeight="Bold"
Text="{Binding FullName}" />
<TextBlock Grid.Row="1"
Text=" FirstName: " />
<TextBlock Grid.Row="1"
Grid.Column="1"
Text="{Binding FirstName}" />
<TextBlock Grid.Row="2"
Text=" Email: " />
<TextBlock Grid.Row="2"
Grid.Column="1"
Text="{Binding Email}" />
</Grid>
</Border>
<Button Style="{StaticResource openButton}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
This is my window
<DockPanel>
<v:HeaderTopBar DockPanel.Dock="Top"></v:HeaderTopBar>
<!--<uc:SearchBar DockPanel.Dock="Top" />-->
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem DockPanel.Dock="Right">
<Slider x:Name="zoomSlider"
Width="125"
Value="1"
Minimum=".5"
Maximum="2" />
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right">
<TextBlock>Zoom:</TextBlock>
</StatusBarItem>
<StatusBarItem>
<TextBlock Text="{Binding StatusText}" />
</StatusBarItem>
</StatusBar>
<Expander DockPanel.Dock="Left"
ExpandDirection="Right"
IsExpanded="True"
BorderThickness="0 1 1 1"
BorderBrush="Gray"
Margin="0 2 0 0"
Padding="2">
<Expander.Header>
<TextBlock Text="Contacts"
FontSize="14"
FontWeight="Bold">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<v:OwnerSideBar/>
</Expander>
<TabControl x:Name="tabs"
Grid.Column="2"
Margin="5 0">
<TabControl.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=zoomSlider,
Path=Value}"
ScaleY="{Binding ElementName=zoomSlider,
Path=Value}" />
</TabControl.LayoutTransform>
</TabControl>
</DockPanel>
Firstly, ensure that the AllOwners collection you are binding to is an ObservableCollection.
Also, check the Output window in Visual Studio when executing, look for First chance exceptions being caught. This will be a clue as to where your binding problem will be.
I like to put a textblock on the View bound to the Items.Count property on the ItemsControl so that you can see if it is binding and not rendering anything or not binding correctly.
Give the ItemsControl a name, then put a textblock in:
<TextBlock Text="{Binding ElementName=itemControl1,Path=Items.Count}/>
This might be something you already looked at, but you might have a binding typo, did you check your output window to see if you get any trace messages?
And I guess I'm blind but I don't see where your usercontrol is in the xaml of the second entry.

Resources