WPF Menu item right alignment - wpf

I have the following menu. I am trying to right align the content of the menu.
<Menu Grid.ColumnSpan="3">
<MenuItem Header="Items">
<MenuItem>
<MenuItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Item 1" Grid.Column="0" HorizontalAlignment="Stretch" />
<Button Grid.Column="1" Content="E" />
<Button Grid.Column="2" Content="D" />
</Grid>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Item 2" Grid.Column="0" HorizontalAlignment="Stretch" />
<Button Grid.Column="1" Content="E" />
<Button Grid.Column="2" Content="D" />
</Grid>
</MenuItem.Header>
</MenuItem>
</MenuItem>
</Menu>
What is displayed is as below:
------------------
Item 1 D E |
------------------
Item 2 D E |
------------------
There is still lot of space left after E.
What I am expecting is:
------------------
Item 1 D E |
------------------
Item 2 D E |
------------------
I want the D and E to be aligned to the right where as the Item 1 and Item 2 are aligned to the left.
I tried playing with HorizontalAlignment with no help to find the answer.

I'm more of a dockpanel type of guy. How about you try:
<MenuItem>
<MenuItem.Header>
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Right" Content="E" />
<Button DockPanel.Dock="Right" Content="D" />
<TextBlock DockPanel.Dock="Left" Text="Item 1" />
</DockPanel>
</MenuItem.Header>
</MenuItem>

You can use DockPanel instead of Grid for that purpose. Also try to set Width of your menu items explicitly. Like this:
<MenuItem>
<MenuItem.Header>
<DockPanel LastChildFill="False" Width="250">
<TextBlock Text="Item 1" DockPanel.Dock="Left" HorizontalAlignment="Stretch" />
<Button DockPanel.Dock="Right" Content="E" />
<Button DockPanel.Dock="Right" Content="D" />
</DockPanel>
</MenuItem.Header>
</MenuItem>

Related

how to auto resize of childerin in horizontal stackPanel WPF

I try to build a title bare like Google Chrome title bar in WPF
I made the following
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<!--taps -->
<StackPanel Orientation="Horizontal" Grid.Column="0">
<!--open taps-->
<local:TitleWindowTap />
<local:TitleWindowTap />
<!--add tap button-->
<Button Style="{StaticResource MaterialDesignIconButton}">
<materialDesign:PackIcon Kind="AddCircle"/>
</Button>
</StackPanel>
<!--window control buttons-->
<StackPanel Orientation="Horizontal" Grid.Column="1">
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowMinimize"/>
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowMaximize"/>
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowClose"/>
</Button>
</StackPanel>
</Grid>
and the code for the TitleWindowTap is a userControl as following
<Border Margin="5 5 0 5" BorderBrush="{DynamicResource SecondaryHueMidBrush}" BorderThickness="1" CornerRadius="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource MaterialDesignIconButton}" Grid.Column="1">
<materialDesign:PackIcon Kind="WindowClose"/>
</Button>
<TextBlock x:Name="txtBlock" d:Text="very long title bla bls" VerticalAlignment="Center" Padding="5" FontSize="20" TextTrimming="CharacterEllipsis">
no title
</TextBlock>
</Grid>
</Border>
problem
when I add a new tap (manually in XML) it over the window controls like the following
My question
how to auto resize this taps to fit the available space ?
If you want the taps to be auto-resized you should get rid of the StackPanel and use a Panel that actually resizes its children. You could for example add a ColumnDefinition per TitleWindowTap:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<!--open taps-->
<local:TitleWindowTap />
<local:TitleWindowTap Grid.Column="1" />
<!--add tap button-->
<Button Grid.Column="2" Style="{StaticResource MaterialDesignIconButton}">
<materialDesign:PackIcon Kind="Circle"/>
</Button>
<!--window control buttons-->
<StackPanel Orientation="Horizontal" Grid.Column="3">
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowMinimize"/>
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowMaximize"/>
</Button>
<Button Style="{StaticResource MaterialDesignIconButton}" >
<materialDesign:PackIcon Kind="WindowClose"/>
</Button>
</StackPanel>
</Grid>
I would suggest you use ItemsControl and its ItemTemplate and ItemsPanel. What you really want works nicely via ItemsSource binding to ObservableCollection<YourDataType>. Most likely you will need to have the "add" button as part of your data collection, but with another DataTemplate.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<!--taps -->
<DockPanel Grid.Column="0">
<!--open taps-->
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:TitleWindowTap />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Columns="{Binding Items.Count}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<!--add tap button-->
<Button Style="{StaticResource MaterialDesignIconButton}"
Click="Button_Click">
<materialDesign:PackIcon Kind="AddCircle"/>
</Button>
</DockPanel>

Toggle button and vertical grid splitter is not working simultaneously

This is my sample code ,Please help me to achieve both goals simultaneouslyImage
On click toggle button collapse and visible column and vertical split button.
In the below fig. First add toggle button and First column contain two column .
It contains second sub column is collapse or disable based on toggle button click.
and Spltter is working on outside two main column please help me as soon as possible
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="5"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Border Background="Green"
Grid.Column="0">
<Grid Grid.Column="1"
Visibility="{Binding IsChecked, ElementName=toggleButton, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<WrapPanel Grid.Column="1"
Background="Aqua" />
</Grid>
</Border>
<ToggleButton x:Name="toggleButton"
Width="30"
Height="30"
Margin="0,10,10,0"
IsChecked="True"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
<GridSplitter Width="5"
Grid.Column="1"
ResizeBehavior="CurrentAndNext" />
<Grid Grid.Column="2"></Grid>
</Grid>
From reading your question, I believe this is what you are trying to achieve. Please let me know if I didn't understand you properly.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="5" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Grid.Column="0"
Background="Green">
<ToggleButton x:Name="toggleButton"
Width="30"
Height="30"
Margin="0,10,10,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsChecked="True" />
</Border>
<Grid
Grid.Column="1"
MaxWidth="300"
Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
<WrapPanel Background="Aqua">
<TextBlock
Margin="8"
Text="Item 01" />
<TextBlock
Margin="8"
Text="Item 02" />
<TextBlock
Margin="8"
Text="Item 03" />
<TextBlock
Margin="8"
Text="Item 04" />
<TextBlock
Margin="8"
Text="Item 05" />
</WrapPanel>
</Grid>
<GridSplitter
Grid.Column="1"
Width="5"
Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Grid Grid.Column="3">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="Column 2" />
</Grid>
</Grid>

Create custom menu with a button wpf

This is my custom title bar:
That three dot button is a button control. I want to create a menu like this (drew by paint!):
But I don't have any idea. I know there is a "Menu" control but I couldn't use it as I wanted.
"More" button code:
<Button x:Name="More" Grid.Column="1" Style="{DynamicResource TitleBarButton}" IsTabStop="False" Focusable="False">
<Button.Background>
<ImageBrush ImageSource="icons/More.png"/>
</Button.Background>
</Button>
You may replace the Button with a ToggleButton and use a Popup that you bind to the ToggleButton's IsChecked property:
<ToggleButton x:Name="More" Grid.Column="1" Style="{DynamicResource TitleBarButton}" IsTabStop="False" Focusable="False">
<ToggleButton.Background>
<ImageBrush ImageSource="icons/More.png"/>
</ToggleButton.Background>
</ToggleButton>
<Popup IsOpen="{Binding IsChecked, ElementName=More}"
PlacementTarget="{Binding ElementName=More}"
Placement="Bottom">
<StackPanel Width="100" Background="Yellow">
<TextBlock Text="Check For Updates" />
<Grid Background="DarkGray" Height="3" />
<TextBlock Text="Do something else" />
</StackPanel>
</Popup>
You may of course replace the contents of the Popup with whatever you want.
enter image description here
You may need setup menu items to act as buttons
(more WPF button feature int this book)
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Green">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.0*" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="40" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" >
<Menu Height="40" Width="40" Background="Green" >
<MenuItem >
<!-- MENU HEADER -->
<MenuItem.Header>
<Border>
<Image Source="/WpfMenuButton;component/Images/DotsImg.PNG" />
</Border>
</MenuItem.Header>
<!-- MENU ITEM UPDATE -->
<MenuItem Click="CheckUpdate_Click" Background="Chocolate">
<MenuItem.Header>
<TextBlock Text="Check for update" VerticalAlignment="Center" HorizontalAlignment="Center"
Height="30" Width="100" />
</MenuItem.Header>
</MenuItem>
<!-- MENU ITEM WIFI -->
<MenuItem Click="DoSomethingElse_Click" Background="LightGreen">
<MenuItem.Header>
<TextBlock Text="Do something else" VerticalAlignment="Center"
HorizontalAlignment="Center" Height="30" Width="140" />
</MenuItem.Header>
</MenuItem>
<!-- MENU ITEM ABOUT -->
<MenuItem Click="MenuAbout_Click" Background= "LightBlue">
<MenuItem.Header>
<TextBlock Text="About" VerticalAlignment="Center" HorizontalAlignment="Center"
Height="30" Width="140" />
</MenuItem.Header>
</MenuItem>
</MenuItem>
</Menu>
</Grid>
<Grid Grid.Column="2" >
<Button Content="-" Foreground="White" FontSize="28" Background="Green"/>
</Grid>
<Grid Grid.Column="3" >
<Button Content="X" Foreground="White" FontSize="28" Background="Green"/>
</Grid>
</Grid>
</Grid>

How to keep elements in ScrollViewer in sight, regardless of scrolling

In Silverlight, is it possible to let certain elements inside a ScrollViewer stay in view? By this I mean that certain elements should always be visible, regardless of where the scroll position currently is.
Take this XAML for example (you can put it in something like KaXaml of XamlPad):
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ScrollViewer Width="250" Height="100" HorizontalScrollBarVisibility="Visible">
<StackPanel>
<Grid Width="350" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Button Content="1" Grid.Column="0" BorderThickness="2" Width="50" />
<Button Content="2" Grid.Column="1" BorderThickness="2" Width="50" />
<Button Content="3" Grid.Column="2" BorderThickness="2" Width="50" />
<Button Content="4" Grid.Column="3" BorderThickness="2" Width="50" />
<Button Content="5" Grid.Column="4" BorderThickness="2" Width="50" />
<Button Content="6" Grid.Column="5" BorderThickness="2" Width="50" />
<Button Content="X" Grid.Column="6" BorderThickness="2" Width="50" />
</Grid>
<Grid Width="350" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Button Content="1" Grid.Column="0" BorderThickness="2" Width="50" />
<Button Content="2" Grid.Column="1" BorderThickness="2" Width="50" />
<Button Content="3" Grid.Column="2" BorderThickness="2" Width="50" />
<Button Content="4" Grid.Column="3" BorderThickness="2" Width="50" />
<Button Content="5" Grid.Column="4" BorderThickness="2" Width="50" />
<Button Content="6" Grid.Column="5" BorderThickness="2" Width="50" />
<Button Content="X" Grid.Column="6" BorderThickness="2" Width="50" />
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>
I would like to keep the 'X' buttons in sight, regardless of how much you scroll left or right. Of course, when scrolling down or up, the 'X' buttons should follow the scrolling.
I'm not saying the structure of my XAML is ideal, but each row is a databound to a different item, so each row is a data template. I can't put one big grid in the scrollviewer or have columns instead of rows as templates (at least, I think I can't).
Ya no sweat, just layer those elements over your Scrollviewer in a Panel like this;
<Grid>
<ScrollViewer>
... Scroll Viewer Embedded Stuff ...
</ScrollViewer>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center" VerticalAlignment="Top" Margin="5">
<Button Content="Button1"/>
<Button Content="Button1"/>
<Button Content="Button1"/>
<Button Content="Button1"/>
<Button Content="Button1"/>
</StackPanel>
</Grid>
You could even go a step further and set a EventTrigger to make your buttons visible on MouseEnter and disappear on MouseLeave if you wanted but this should get you started. Best of luck!
You might have more luck using a DataGrid and have the X buttons as a frozen column.

WPF: Align last TWO controls in StackPanel/DockPanel on the very right side

Thats my code so far which does not work:
<DockPanel >
<Button Content="Start" Command="{Binding Path=FirstDateCommand}" />
<Button Content="Back" Command="{Binding Path=PreviousDateCommand}" />
<DatePicker Width="150"
SelectedDate="{Binding Path=SelectedDate}"
DisplayDateStart="{Binding Path=MinDate}"
DisplayDateEnd="{Binding Path=MaxDate}" SelectedDateFormat="Long" />
<Button Content="Forward" Command="{Binding Path=NextDateCommand}" />
<Button Content="End" Command="{Binding Path=LastDateCommand}" />
<Button Command="{Binding PrintCommand}" Content="Print Planner" />
<Button Command="{Binding ToggleDocumentsCommand}" Content="Show Docs" />
<Button Command="{Binding MaterialExplorerShowCommand}" Content="Browse Docs" />
<Button Command="{Binding LessonPlannerCommand}" Content="Edit Planner" />
<TextBox Text="{Binding SearchText,Mode=TwoWay}" Width="50" />
<Button Command="{Binding FindAllCommand}" Content="Search" />
<DockPanel DockPanel.Dock="Right" HorizontalAlignment="Right">
<TextBlock Text="class code:" VerticalAlignment="Center" />
<ComboBox
ItemsSource="{Binding GroupViewModelList}"
Style="{StaticResource GroupViewModelStyle}"
ItemTemplate="{StaticResource GroupViewModelItemTemplate}"
Width="100"/>
</DockPanel>
</DockPanel>
How can I set the 2 last controls on the image on the very right side?
UPDATE:
<Grid Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Margin="10,10,10,0" Grid.Row="0" Name="ButtonBar">
<StackPanel FocusManager.IsFocusScope="True" Orientation="Horizontal">
<ComboBox
AlternationCount="2"
FontSize="16"
VerticalContentAlignment="Center"
Width="100"
ItemContainerStyle="{StaticResource alternateColor}"
ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}" x:Name="fontComboFast">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Width="100" Text="{Binding}" FontFamily="{Binding }" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!--<View:FormatButtonBar />-->
<View:DateNavigatorView />
<View:LessonPlannerView />
<!--<View:TextFormatBarUC />-->
</StackPanel>
</Grid>
The 2 controls are in the LessonPlannerView (UserControl)
Inside the LessonPlannerView you find this code:
...
<Grid >
<DockPanel>
<Button Command="{Binding PrintCommand}" Content="Print Planner" />
<Button Command="{Binding ToggleDocumentsCommand}" Content="Show Docs" />
<Button Command="{Binding MaterialExplorerShowCommand}" Content="Browse Docs" />
<Button Command="{Binding LessonPlannerCommand}" Content="Edit Planner" />
<TextBox Text="{Binding SearchText,Mode=TwoWay}" Width="50" />
<Button Command="{Binding FindAllCommand}" Content="Search" />
<StackPanel x:Name="ClassCodeChooser" Orientation="Horizontal" DockPanel.Dock="Right" HorizontalAlignment="Right">
<TextBlock Text="class code:" VerticalAlignment="Center" />
<ComboBox ItemsSource="{Binding SchoolclassCodeList}"
/>
</StackPanel>
</DockPanel>
</Grid>
</UserControl>
That should be fine but you really don't need the nested DockPanel's. You could change the inner DockPanel to a horizontal StackPanel.
But the real problem is that your outer DockPanel doesn't seem to be expanding to the full width of its container. Set a Background on the outer DockPanel to give you a visual indication of why it isn't filling out its container.
In response to the comment thread below, adding the following example
<Grid Name="ButtonBar">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0">
<View:FormatButtonBar /> <!-- this will dock left -->
<View:DateNavigatorView /> <!-- this will dock left -->
<View:LessonPlannerView /> <!-- this will dock left -->
<View:TextFormatBarUC /> <!-- this will fill -->
</DockPanel>
</Grid>

Resources