I have two different panels like this
.
When i click on the first button, it should display some text, second button should display a datagrid and so on.
How do i change the elements of the right hand panel to achieve this. Initially i just used different windows. Is there a way to call them into the panel ? Then I though of hiding elements based on the button clicked, but that would look like a mess. Should i code the elements when a button is clicked otherwise ? How is this functionality usually added ? What concepts do i need to learn to implement this ?
After coming across this question and seeing the absolutely poor answers that you had been provided with, I felt obliged to offer you a decent answer. There are many different ways of achieving your requirements. Here is probably, the simplest method:
Declare one Grid in MainWindow that displays your three Buttons on the left hand side and the three possible controls on the right hand side:
<Grid>
<Grid.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="40" />
<Setter Property="Content" Value="Button" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Row="0" Name="Button1" Style="{StaticResource ButtonStyle}" />
<ToggleButton Grid.Row="1" Name="Button2" Style="{StaticResource ButtonStyle}" />
<ToggleButton Grid.Row="2" Name="Button3" Style="{StaticResource ButtonStyle}" />
<TextBlock Grid.Column="1" Grid.Row="0" Name="TextBlock" Text="Here is some text"
HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding
IsChecked, ElementName=Button1, Converter={StaticResource
BooleanToVisibilityConverter}}" />
<Rectangle Grid.Column="1" Grid.Row="1" Name="Rectangle" Width="150" Height="40"
Fill="LightGreen" Stroke="Black" Visibility="{Binding IsChecked, ElementName=
Button2, Converter={StaticResource BooleanToVisibilityConverter}}" />
<RadioButton Grid.Column="1" Grid.Row="2" Name="RadioButton" Content="Here is an
option" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{
Binding IsChecked, ElementName=Button3, Converter={StaticResource
BooleanToVisibilityConverter}}" />
</Grid>
Note that I used ToggleButtons here simply because they have a bool IsChecked property that is set when they are clicked on and can be used to show and hide the controls on the right hand side. To do this, we use a BooleanToVisibilityConverter (which was introduced into the .NET Framework in .NET 4.5) to convert our bool ToggleButton.IsChecked property values into Visibility values.
Now this example probably wasn't exactly what you were thinking of, but I'm sure that it will give you enough of an example for you to experiment with and come up with your desired UI... remember that you are going to have to do some work too.
Create your Xaml page with all the views Textboxt, DataGrid and TextBox2. then you just need to play with the Visibility of controls
Related
I have a user control with many sub controls within a grid. Since there are many controls per row, I'm controlling the visibility of the controls by setting the row height of their containing row to 0 (to hide them).
I'm using a validation template on some of these controls and displaying an icon next to the control using AdornedElementPlaceholder.
Since I'm not actually setting the visibility property of the adorned control, but instead hiding the row, the validation icon is not collapsed with the rest of the control.
Here's an abridged version of my XAML code:
<UserControl
<UserControl.Resources>
<ControlTemplate x:Key="ValidationTemplate" TargetType="Control">
<DockPanel>
<Grid
Width="16"
Height="16"
Margin="10,0,0,0"
VerticalAlignment="Center"
DockPanel.Dock="Right">
<Image Source="{x:Static icons:Icons.ValidationIcon}" ToolTip="{Binding Path=ErrorContent}" />
</Grid>
<AdornedElementPlaceholder />
</DockPanel>
</ControlTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="{Binding Path=ScheduleType, Mode=OneWay, Converter={StaticResource ScheduleTypesToGridRowHeightConverter}, ConverterParameter={x:Static local:ScheduleTypes.Other}}"/>
<RowDefinition Height="{Binding Path=ScheduleType, Mode=OneWay, Converter={StaticResource ScheduleTypesToGridRowHeightConverter}, ConverterParameter={x:Static local:ScheduleTypes.Fixed}}"/>
<RowDefinition Height="{Binding Path=ScheduleType, Mode=OneWay, Converter={StaticResource ScheduleTypesToGridRowHeightConverter}, ConverterParameter={x:Static local:ScheduleTypes.Weekly}}"/>
<RowDefinition Height="{Binding Path=ScheduleType, Mode=OneWay, Converter={StaticResource ScheduleTypesToGridRowHeightConverter}, ConverterParameter={x:Static local:ScheduleTypes.FreeText}}"/>
</Grid.RowDefinitions>
<controls:DateInputBox
Grid.Column="2"
Grid.Row="5"
Height="28"
HorizontalAlignment="Left"
Watermark=""
Width="110"
Text="{Binding StartDateText, ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
Validation.ErrorTemplate="{StaticResource ValidationTemplate}"
VerticalAlignment="Center"
ParseComplexDates="True"/>
</Grid>
</UserControl>
From what I understand from a little research is that the validation icon is being displayed in the adorner layer, so doesn't collapse with the rest of the controls.
I'm now thinking that the "row height visibility pattern" was maybe not the best approach ;-) Is there a way I can get this to work without having to completely change my design? I do have a workaround using my view model but I'd like to explore other options first.
If you really whant to stick with the design, you could remove and add the adornents depending of what you whant to display. However, this would be pretty messy and defeat the point of sticking with the current desing for simplicity in the first place.
The concept of hiding elements by setting their parent element size to zero is indeed not the best option. Partly because of the exact issue you mentioned. (The adornents visibility is dependent on its owners visibility. And the owner elements visibility is visible, there is just no space to render it.)
A better option would be to only show whatever is to be shown. An easy way to accomplish this would be to encapsulate all the elements you whant to hide/show together inside one element or user control and then hide or show only that parent element or user control.
This could for instance look like this:
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Border Grid.Row="1" Visibility="{Binding FixedIsVisible, Converter={StaticResource BoolToVis}">
<!-- fixed shedule content here -->
</Border>
<Border Grid.Row="1" Visibility="{Binding WeeklyIsVisible, Converter={StaticResource BoolToVis}">
<!-- weekly shedule content here -->
</Border>
<Border Grid.Row="1" Visibility="{Binding FretextIsVisible, Converter={StaticResource BoolToVis}">
<!-- free text shedule content here -->
</Border>
</Grid>
By using some other converter you also yould directly bind you ScheduleType so you dont need to touch your view model.
A maybe even better option would be to make it so that only the elements you need at a time exist inside the view. This could be acomplished by defining different user controls and then have your grid line contain only the desired control at a time. (I might add an example for this later when i have time to do so.)
I'm writing a UWP app to track TV shows watched/purchased/streamed etc and
am going absolutely crazy trying to get grid columns inside a DataTempate to stretch their width as it seems there is a bug in XAML which ignores the * width definition. I need the first column in the ListView (the show Title) to take up the remaining space (hence the column definition = "*") and while it will do that in the HeaderTemplate it absolutely refuses to do it inside the DataTemplate so the whole grid just ends up being all wonky and out of alignment as the Title column only uses the space it needs on each line.
My XAML is below - in the ItemTemplate DataTemplate template I am binding to an instance of an object called TVShow which is in an observable collection in my main view model. (I have not included the ViewModel or TVShow class definition here as I know this is a purely XAML issue).
The only thing that worked so far is having an extra property in my TVShow class that stores the correct width of the column (by subtracting the widths of the other three columns from the grid size (fetched in the view code behind) but this causes the whole list to reformat itself after initally displaying which looks ugly, not to mention awful programming.
So I'm looking for ideas on how to solve this - I could move the property for the correct column width in the main viewmodel but then how do I bind to that in the template given I am binding to "TVShow"? Or do I have to take the content out of the DataTemplate and put in a UserControl? I have wasted so much time on something that is so ridiculously simple - this bug seems to have been around since WPF so why haven't MS ever fixed this - very frustrating.
<HubSection Name="hsShows" Width="{Binding HubSectionWidth}" MinWidth="430" MaxWidth="640"
VerticalAlignment="Top" HorizontalAlignment="Stretch" Background="{StaticResource Dark}" >
<HubSection.Header>
<TextBlock Text="Shows" TextLineBounds="TrimToBaseline" OpticalMarginAlignment="TrimSideBearings"
FontSize="24" Foreground="{StaticResource Light}"/>
</HubSection.Header>
<DataTemplate x:DataType="local:MainPage">
<ListView Name="lvwShows"
Width="{Binding HubSectionGridWidth}"
Grid.Row="0"
Foreground="{StaticResource Light}"
Background="{StaticResource Dark}"
Margin="-14,20,0,0"
Loaded="lvwShows_Loaded"
ItemsSource="{Binding AllShows}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
IsSwipeEnabled="True"
IsItemClickEnabled="True"
SelectedItem="{Binding SelectedTVShow, Mode=TwoWay}"
SelectionMode="Single"
ScrollViewer.VerticalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.HeaderTemplate>
<DataTemplate>
<Grid Width="{Binding HubSectionGridWidth}" Height="Auto" Background="DarkGreen" Margin="15,5,5,5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Title" FontSize="16" FontWeight="Bold" Foreground="{StaticResource Bright}"
VerticalAlignment="Bottom" HorizontalAlignment="Left"
Tag="TITLE,ASC" Tapped="ShowsGridHeading_Tapped"/>
<TextBlock Grid.Column="1" Text="Seasons" FontSize="16" FontWeight="Bold" Foreground="{StaticResource Bright}"
VerticalAlignment="Bottom" HorizontalAlignment="Center"
Tag="SEASONS,ASC" Tapped="ShowsGridHeading_Tapped"/>
<TextBlock Grid.Column="2" Text="Last Watched" FontSize="16" FontWeight="Bold" Foreground="{StaticResource Bright}"
VerticalAlignment="Bottom" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap"
Tag="WATCHED,ASC" Tapped="ShowsGridHeading_Tapped"/>
<TextBlock Grid.Column="3" Text="Last Episode" FontSize="16" FontWeight="Bold" Foreground="{StaticResource Bright}"
VerticalAlignment="Bottom" HorizontalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap"
Tag="EPISODE,ASC" Tapped="ShowsGridHeading_Tapped"/>
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:TVShow">
<Grid Height="Auto" MinWidth="410" MaxWidth="640" Background="Blue" HorizontalAlignment="Stretch" RightTapped="ShowsList_RightTapped">
<FlyoutBase.AttachedFlyout>
<MenuFlyout Placement="Bottom">
<MenuFlyoutItem x:Name="UpdateButton" Text="Update from TVMaze" Click="FlyoutUpdateButton_Click"/>
<MenuFlyoutItem x:Name="RefreshButton" Text="Refresh" Click="FlyoutRefreshButton_Click"/>
<MenuFlyoutItem x:Name="DeleteButton" Text="Delete Show" Click="FlyoutDeleteButton_Click"/>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{x:Bind Title}" Foreground="{StaticResource Light}"
VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{x:Bind Seasons}" Foreground="{StaticResource Light}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="0" Grid.Column="2" Foreground="{StaticResource Light}"
Text="{x:Bind LastWatchedDate, Mode=OneWay, Converter={StaticResource DateTimeFormatConverter}, ConverterParameter='{}{0:dd/MM/yyy HH\\\\:mm}'}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="0" Grid.Column="3" Text="{Binding LastWatchedEpisodeRef}" Foreground="{StaticResource Light}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</HubSection>
Ok, so I ended up adding this XAML into my ListViews (though I know I could have done what Grace suggested but I just find Blend horrific to use) - it was the HorizontalContentAlignment that actually did the trick!
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
If you have Correct width in viewmodel you can Bind it like this
Width={Binding ElementName = ListViewname,Path=DataContext.width}
This problem is caused by the default template of the ListViewItem, to make the Grid stretch inside of the items, you can open the Document Outline label => find your ListView control and right click on it, then choose Edit Additional Templates => select Edit Generated Item Container (ItemContainerStyle), and at last Edit a Copy.
Then you will find this template in your Page resources, please change the code:
<Setter Property="HorizontalContentAlignment" Value="Left" />
To:
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
Then your problem can be solved.
I saw you've more then one ListView, if you want this style target all the ListView in this page, you can remove the x:Key attribute of this template and remove the ItemContainerStyle with the StaticResource which is generated by the action upper.
Don't be frustrating, I think you have developed WPF before, it's easy to learn UWP. Editing the template or the styles of the controls can solve many layout problem, here is some default templates and styles of different controls, you may take a look next time you have such problem.
If you have questions about how to develop an UWP app, you can refer to Develop UWP apps, and if you have some problems with the APIs, you may refer to Reference for Universal Windows apps.
If you need help or suggestion, you may ask question here, people here are glad to help.
i have a listbox with a lot of items, and each items when clicked go to a new page, what i want is when i return from the second page, stay at the same position of the item is clicked!
Thats my list!
<ListBox x:Name="list" Loaded="ListView_Loaded" SelectedItem="true" SelectionChanged="searchResultsList_SelectionChanged" ItemsSource="{Binding}" Background="{x:Null}">
<!--<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,0,0,15" />
</Style>
</ListView.ItemContainerStyle>-->
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Width="80" Height="80">
<Image Source="{Binding Caminho}" />
</Border>
<StackPanel Margin="0,16,0,0" Grid.Column="2">
<TextBlock Foreground="White" Text="{Binding NomeCurso}" TextWrapping="Wrap" FontSize="{StaticResource TextStyleExtraLargeFontSize}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
thanks!
If you are using WinRT you can write the following code in your page constructor to cache it, this way the positions will be intact after you go back to this page:
this.NavigationCacheMode = NavigationCacheMode.Required;
And from your sample I cant really see if you are using ListBox or ListView, I will presume ListView which is better as the ListBox is somewhat not needed anymore.
One thing I also noticed is that you use a simple {Binding} for your ItemsSource so maybe it is reset every time you go back because of this (if you are doing something that does this, as this is not visible from your sample code). I always have an additional property of type ObservableCollection and bind to it for example ItemsSource={Binding MyItems}. This way the list is reset only when I reset the property MyItems.
I have started with XAML as part of my freetime and now I have a problem with the padding of the standard button.
I have the following code for a grid which resides in another grid, so I have four grids inside my page and the problem is that the buttons are cut off and I am not able to change the width or the padding of the buttons.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Center" FontSize="24"/>
<Button x:Name="Player2MinusButton" Content="-" Grid.Row="1" Grid.Column="0" FontSize="20" ></Button>
<Button x:Name="Player2PlusButton" Content="+" Grid.Row="1" Grid.Column="2" FontSize="20" ></Button>
</Grid>
The problem is now, that the button is cut of as you could see in the screenshot here:
I have already tried to set a negative padding/margin and also to make a Custom Style:
<Style TargetType="Button" x:Key="ButtonStyle">
<Setter Property="Padding" Value="-10,0"/>
</Style>
Thanks for your hints and I hope I have nothing forgotten in my first question.
Michael
Since you want a narrower than standard button set the Buttons' MinWidth property:
<Button x:Name="Player2PlusButton" Content="+" Grid.Row="1" Grid.Column="2" FontSize="20" MinWidth=50 AutomationProperties.Name="Plus Button" ></Button>
If you copy the button template (right click on the button in the designer then select Edit Template... and follow the prompts) you'll find the following:
<x:Double x:Key="PhoneButtonMinHeight">57.5</x:Double>
<x:Double x:Key="PhoneButtonMinWidth">109</x:Double>
I assume you're running on the phone: the Windows Store Button template is different and doesn't set the minimums. Your buttons come out small there by default.
I have been working with MahApps Metro UI for couple days now and i have realy enjoyed it. WHen looking through their documentation, i wanted to use the tile control and make something along the lines of this:
Their documentation, located on this page: http://mahapps.com/controls/tile.html , only tells me this:
The following XAML will initialize a Tile control with its Title set to "Hello!" and its Count set to 1.
<controls:Tile Title="Hello!"
TiltFactor="2"
Width="100" Height="100"
Count="1">
</controls:Tile>
When i entered this into my simple application, i get one small rectangle. How am i actually supposed to use the control to mimic the Windows 8 start screen with tiles?
I'm currently building a large application using the MahApps Metro library and it's amazing! In terms of getting an app to look like the Windows 8 start screen, heres quick example I whipped up.
XAML
<Window x:Class="Win8StartScreen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Title="MainWindow" Height="513" Width="1138" WindowState="Maximized" WindowStyle="None" Background="#191970">
<Window.Resources>
<Style x:Key="LargeTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="300" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
<Style x:Key="SmallTileStyle" TargetType="mah:Tile">
<Setter Property="Width" Value="147" />
<Setter Property="Height" Value="125" />
<Setter Property="TitleFontSize" Value="10" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="87*"/>
<ColumnDefinition Width="430*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="83*"/>
<RowDefinition Height="259*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Text="Start"
FontWeight="Light"
Foreground="White"
FontSize="30"
FontFamily="Segoe UI" />
<WrapPanel Grid.Row="1" Grid.Column="1" Width="940" Height="382" HorizontalAlignment="Left" VerticalAlignment="Top">
<mah:Tile Title="Mail" Style="{StaticResource LargeTileStyle}" Content="ImageHere" Background="Teal" Margin="3"/>
<mah:Tile Title="Desktop" Style="{StaticResource LargeTileStyle}" Margin="3">
<mah:Tile.Background>
<ImageBrush ImageSource="Images/windesktop.jpg" />
</mah:Tile.Background>
</mah:Tile>
<mah:Tile Title="Finance" Style="{StaticResource LargeTileStyle}" Background="Green" />
<mah:Tile Title="People" Style="{StaticResource LargeTileStyle}" Background="#D2691E" />
<mah:Tile Title="Weather" Style="{StaticResource LargeTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Weather" Style="{StaticResource SmallTileStyle}" Background="#1E90FF" />
<mah:Tile Title="Store" Style="{StaticResource SmallTileStyle}" Background="Green" />
</WrapPanel>
</Grid>
</Window>
There are lots of ways to do this to make it cleaner and more reusable using styles and templates, but this was just a quick way to show the use of the Tiles control.