I want to show whole of the ListBox when its bounds are overflowed from main window. DatePicker behaves just I want to do (see the attached image). How can I implement to do this?
Screen capture describing what DatePicker can do and I can't do
<!-- MainWindow.xaml -->
<Window x:Class="OverflowSample.MainWindow"
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"
xmlns:local="clr-namespace:OverflowSample"
mc:Ignorable="d"
Title="MainWindow" Height="130" Width="500">
<Grid>
<DatePicker HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<Button x:Name="buttonShowListBox" Content="Show" HorizontalAlignment="Left" Margin="240,10,0,0" VerticalAlignment="Top" Width="75" Click="buttonShowListBox_Click"/>
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="160" Margin="250,40,0,-90" VerticalAlignment="Top" Width="200" FontSize="24" Visibility="Collapsed">
<ListBoxItem Content="Three"/>
<ListBoxItem Content="Two"/>
<ListBoxItem Content="One"/>
<ListBoxItem Content="Zero"/>
</ListBox>
</Grid>
</Window>
// MainWindow.xaml.cs
using System.Windows;
namespace OverflowSample
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void buttonShowListBox_Click(object sender, RoutedEventArgs e)
{
listBox.Visibility = (listBox.Visibility == Visibility.Visible) ?
Visibility.Collapsed :
Visibility.Visible;
}
}
}
DatePicker uses a Popup and puts the calendar inside that.
the .net framework source is available to see for yourself:
http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/DatePicker.cs,c20427230c18ba13
Related
I am trying to implement basic navigation in UWP, all according to https://learn.microsoft.com/en-us/windows/uwp/design/basics/navigate-between-two-pages.
I've made the example as simple as possible. Made a main application window, with a frame and 2 buttons in it. Clicking a button will navigate the frame to display the content of page 1 or 2 respectively. The page contain as simple textblock
Code compiles and runs, navigating the frame works, however instead of the content of the page (the XAML content that is), it shows the name of the page object (i.e. ConceptTestApp.Page1 resp. ConceptTestApp.Page2) instead of the content of the page (i.e. the textblock 'This is Page 1' resp. 'This is Page 2').
I cannot see what I am doing wrong here. Any help greatly appreciated.
Application XAML
<Window x:Class="ConceptTestApp.MainWindow"
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"
xmlns:local="clr-namespace:ConceptTestApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button x:Name="btnPage1" FontSize="14" Height="20" Width="120" Content="Ga naar Pagina 1" Click="BtnPage1_Click" Margin="10,0" />
<Button x:Name="btnPage2" FontSize="14" Height="20" Width="120" Content="Ga naar Pagina 2" Click="BtnPage2_Click" Margin="10,0" />
</StackPanel>
<Frame x:Name="rootFrame" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" NavigationUIVisibility="Hidden" Width="600" Height="450"/>
</StackPanel>
</Grid>
</Window>
Application code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ConceptTestApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.rootFrame.Navigate(typeof(Page1));
}
private void BtnPage1_Click(object sender, RoutedEventArgs e)
{
// go to Pagina 1
this.rootFrame.Navigate(typeof(Page1));
}
private void BtnPage2_Click(object sender, RoutedEventArgs e)
{
// go to Pagina 2
this.rootFrame.Navigate(typeof(Page2));
}
}
}
Page1 XAML
<Page x:Class="ConceptTestApp.Page1"
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"
xmlns:local="clr-namespace:ConceptTestApp"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="600"
Title="Page1">
<Grid>
<TextBlock x:Name="pageTitle" FontSize="36" >This is Page 1</TextBlock>
</Grid>
</Page>
Page2 XAML
<Page x:Class="ConceptTestApp.Page2"
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"
xmlns:local="clr-namespace:ConceptTestApp"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="600"
Title="Page2">
<Grid>
<TextBlock x:Name="pageTitle" Text="This is Page 2" FontSize="24" />
</Grid>
</Page>
(both pages don't have any code behind, only default init code)
It looks like you doing a WPF application rather than a UWP application. This does work in a UWP application if you use MainPage
For example,
<Page
x:Class="PageIssueSOF.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PageIssueSOF"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button x:Name="btnPage1" FontSize="14" Height="20" Width="120" Content="Ga naar Pagina 1" Click="BtnPage1_Click" Margin="10,0" />
<Button x:Name="btnPage2" FontSize="14" Height="20" Width="120" Content="Ga naar Pagina 2" Click="BtnPage2_Click" Margin="10,0" />
</StackPanel>
<Frame x:Name="rootFrame" HorizontalAlignment="Left" Margin="0" VerticalAlignment="Top" Width="600" Height="450"/>
</StackPanel>
</Grid>
</Page>
On a side note NavigationUIVisibility="Hidden" is not available in UWP so has been removed in the example above.
It seems you create a WPF application. And in WPF, when you use Frame.Navigate, it is different with UWP, you need to pass the page object instead of Type.
private void BtnPage1_Click(object sender, RoutedEventArgs e)
{
// go to Pagina 1
this.rootFrame.Navigate(new Page1());
}
private void BtnPage2_Click(object sender, RoutedEventArgs e)
{
// go to Pagina 2
this.rootFrame.Navigate(new Page2());
}
I want to develop a desktop application based on WPF. How do I navigate through C # code from one window to another in a window? in the other word, I have tried to set up a click event for a radiobutton that opens another window in frame or border.
<Window x:Class="WpfNavigation2.MainWindow"
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"
xmlns:local="clr-namespace:WpfNavigation2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" Closing="Window_Closing">
<Grid>
<Border Margin="10,100,10,10" Background="AliceBlue">
<Grid Name="contergrid">
</Grid>
</Border>
<RadioButton x:Name="radioButton" Content="RadioButton1" HorizontalAlignment="Left" Margin="60,0,0,0" VerticalAlignment="Top" Click="btn1"/>
<RadioButton x:Name="radioButton1" Content="RadioButton2" HorizontalAlignment="Left" Margin="60,37,0,0" VerticalAlignment="Top" Click="btn2"/>
<RadioButton x:Name="radioButton2" Content="RadioButton3" HorizontalAlignment="Left" Margin="60,68,0,0" VerticalAlignment="Top" Click="btn3"/>
</Grid>
</Window>
private void btn1(object sender, RoutedEventArgs e)
{
//open window 1 in border
}
What you are looking for is a ContentPresenter. You can put all kinds of content in a ContentPresenter for example a control
<Border Margin="10,100,10,10" Background="AliceBlue">
<ContentPresenter Name="contentFrame">
</ContentPresenter>
</Border>
private void btn1(object sender, RoutedEventArgs e)
{
Grid grd = new Grid();
grd.Background = new SolidColorBrush(Colors.HotPink);
contentFrame.Content = grd; // replace me with your control / page / window1
}
I want to make change main panel content when I choice action in menu button.
Like main content page, setting page, content page on Main panel (in code used grid x:Name="main_~~~)
It for use just can make 3 and control visibility??
or Can use include like xml at Android and change include target??
( ex > includelayout="#layout/app_bar_main")
Mainwindow.xaml
<Window x:Class="M_C.MainWindow"
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"
xmlns:local="clr-namespace:M_C"
mc:Ignorable="d"
Title="MainWindow"
Width="1024" Height="768"
WindowStyle="None"
WindowState="Maximized"
WindowStartupLocation="CenterScreen">
<Grid x:Name="wide_Out" Background="#000000">
<Viewbox Stretch="Uniform">
<Grid Width="1024" Height="768" VerticalAlignment="Top">
<DockPanel x:Name="L_black" HorizontalAlignment="Left"
Height="768" LastChildFill="False" VerticalAlignment="Top" Width="62"
Background="#FF242424">
<Button Margin="15,8,0,0" Height="40"
VerticalAlignment="Top" Width="30"/>
</DockPanel>
<DockPanel x:Name="T_blue" HorizontalAlignment="Left"
Height="84" LastChildFill="False" Margin="62,0,0,0" VerticalAlignment="Top"
Width="968" Background="#FF248BC7">
<TextBlock Margin="200,5,200,0" Height="70"
TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Width="554"/>
</DockPanel>
<DockPanel x:Name="L_blue" HorizontalAlignment="Left"
Height="685" LastChildFill="False" Margin="62,83,0,0"
VerticalAlignment="Top" Width="82" Background="#FF248BC7"/>
<DockPanel x:Name="R_blue" HorizontalAlignment="Left"
Height="685" LastChildFill="False" Margin="940,83,0,0"
Background="#FF248BC7" Width="84"/>
<DockPanel x:Name="B_blue" HorizontalAlignment="Left"
Height="90" LastChildFill="False" Margin="143,678,0,0"
VerticalAlignment="Top" Width="799" Background="#FF248BC7">
<Image Margin="250,15,250,15" Height="70"
VerticalAlignment="Top" Width="290" />
</DockPanel>
<!--<DockPanel x:Name="main_content_panel"
HorizontalAlignment="Left" Height="594" LastChildFill="False"
Margin="144,84,0,0" VerticalAlignment="Top" Width="790">-->
<Grid x:Name="main_con_body" Margin="143,82,84,88"
Width="798" Height="594" Background="#ffffff">
</Grid>
<!--</DockPanel>-->
</Grid>
</Viewbox>
</Grid>
</Window>
You can Define Frame inside Your Window and navigate between as many page you want:
<Frame Name="FrameWithinGrid" >
</Frame>
and on button Click you can simply navigate:
private void button1_Click(object sender, RoutedEventArgs e)
{
FrameWithinGrid.Navigate(new System.Uri("Page1.xaml",
UriKind.RelativeOrAbsolute));
}
to know more See here
MVVM Approach
Make main_con_body be a ContentControl
Make Window's DataContext a viewmodel
Bind main_con_body's Content property to a viewmodel property of the data context
Define different DataTemplates for the various types of viewmodels that might be present
I have a MainWindow.Xaml file. And one usercontrol PatientWindow.Xaml. How to load the patient window in mainwindow in MVVM architecture?
MainWindow.Xaml
<Window x:Class="PatientAdminTool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:PatientAdminTool.ViewModel"
xmlns:v="clr-namespace:PatientAdminTool.View"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
ResizeMode="CanResizeWithGrip"
WindowStyle="None"
WindowState="Normal"
Title="PatientAdmin Tools"
Height="750"
Width="1400"
AllowsTransparency="True" MouseLeftButtonDown="OnMouseLeftButtonDown" BorderThickness="1" BorderBrush="#555252" >
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
/>
</WindowChrome.WindowChrome>
</Window>
PatientWindow.xaml
Usercontrol window is mentioned in below
<UserControl x:Class="PatientAdminTool.View.PatientWindow"
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"
xmlns:vm="clr-namespace:PatientAdminTool.ViewModel"
xmlns:v="clr-namespace:PatientAdminTool.View"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" LastChildFill="True" Height="40" Background="#646161" >
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
<TextBlock Margin=" 10,5,0,0" HorizontalAlignment="Center" Text="Patients" FontSize="16" TextAlignment="Center" VerticalAlignment="Center" Foreground="#FFFFFF"/>
</StackPanel>
<StackPanel Margin="10,10,0,0" DockPanel.Dock="Right" Background="Transparent" Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" Width="50" >
<StackPanel Background="Transparent" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Focusable="False" ToolTip="Close" VerticalAlignment="Center" Background="#646161" BorderThickness="0" BorderBrush="Transparent" Padding="-4" Click="Button_Click" >
<Button.Content>
<Grid Width="45" Height="23">
<TextBlock Foreground="White" Text="r" FontFamily="Marlett" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Button.Content>
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</StackPanel>
</DockPanel>
</Grid>
</UserControl>
So I need to load the patient window above of main window using MVVM. Here I need to write load event in corresponding View Model. Please help me to do this.
Just add a ControlPresenter at MainWindow.
<ContentPresenter Content="{Binding YouTypeHere}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type fristViewModel1Type}">
<youControlForViewModel1 />
</DataTemplate>
<DataTemplate DataType="{x:Type secondViewModel2Type}">
<youControlForViewModel2 />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
And you could change Views via binding different VM to ContentPresenter.
So you want to open a new child window using MVVM? I assume you would open it from MainWindowViewModel.
Solution 1: without strict MVVM
Sometimes its fine to open it directly from the ViewModel:
private void OnOpenPatientWindowCommandExecute()
{
var o = new PatientWindow();
o.ShowDialog();
}
For this you would have to change PatientWindow from UserControl to a Window.
Solution 2: strict MVVM
The solutions following strict MVVM are a little more complex. In the solution I write here you would have to use a Service, add it to your MainWindowViewModel and bind a control from the view to a Command in the ViewModel. Also, its written as if you are using Dependency Injection, that's why you see the service injected in the constructor. You can avoid this by just instantiating the service in the constructor.
MainWindowViewModel.cs
using Prism.Wpf.Commands; // For easy commands
using PatientAdminTool.Services; // Where you put your new service
public class MainWindowViewModel
{
private IShowDialogService _ShowDialogService;
public MainWindowViewModel(IShowDialogService showDialogService)
{
_ShowDialogService = showDialogService;
// Or do: _ShowDialogService = new ShowDialogService();
// But that's not a good practice and won't let you test
// this ViewModel properly.
OpenPatientWindowCommand = new DelegateCommand(OnOpenPatientWindowCommandExecute);
}
public ICommand OpenPatientWindowCommand { get; private set; }
private void OnOpenPatientWindowCommandExecute()
{
_ShowDialogService.ShowPatientWindow();
}
}
Services\IShowDialogService.cs
public interface IShowDialogService
{
void ShowPatientWindow();
void ShowOtherWindow();
// ...
}
Services\ShowDialogService.cs
public class ShowDialogService : IShowDialogService
{
public void ShowPatientWindow()
{
var patientWindowViewModel = new PatientWindowViewModel();
var patientWindow = new PatientWindow();
patientWindow.DataContext = patientWindowViewModel;
patientWindow.ShowDialog();
}
public void ShowOtherWindow()
{
// Other window ...
}
}
Finally, you make the connection in the View like this:
MainWindow.xaml
<Window
xmlns:vm="clr-namespace:PatientAdminTool.ViewModel">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Button Command="{Binding OpenPatientCommand}">Open Patient</Button>
</Grid>
</Window>
Haven't tried it in Visual Studio yet but that's the idea.
If it's the only thing you are going to be displaying in the same window, just put your view in there like any other control:
<Window x:Class="PatientAdminTool.MainWindow"
xmlns:v="clr-namespace:PatientAdminTool.View"... >
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"/>
</WindowChrome.WindowChrome>
<v:PatientWindow/>
</Window>
Do you have a root ViewModel for your window? If so, you can bind to a PatientViewModel:
<v:PatientWindow DataContext="{Binding PatientViewModel}"/>
If not, it's common to set the first DataContext to a ViewModel in the code-behind like this:
<v:PatientWindow Name="PatientWindowView"/>
and:
public partial class Window
{
public MainWindow()
{
InitializeComponent();
PatientWindowView.DataContext = new PatientWindowViewModel();
}
}
If you want to display more than one View, use a ContentPresenter like Shakra has answered.
If you want to open a new window, use what Alberto Cardona López has suggested.
I have this window defined in C#:
<Window x:Class="VirginOneAccount.AccountInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Account Information" Height="362" Width="614" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="AccountTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AccountName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="418*" />
<ColumnDefinition Width="174*" />
</Grid.ColumnDefinitions>
<ComboBox Height="23" HorizontalAlignment="Stretch" Margin="40,16,42,0" Name="AccountsList" VerticalAlignment="Top" Width="Auto" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}" ItemTemplate="{StaticResource AccountTemplate}" AllowDrop="False" DataContext="{Binding}" IsEnabled="True" SelectionChanged="AccountsList_SelectionChanged" />
<Button Content="Save Changes" Height="23" HorizontalAlignment="Left" Margin="40,0,0,10" Name="saveChanges" VerticalAlignment="Bottom" Width="90" IsEnabled="False" Click="saveChanges_Click" />
</Grid>
Then in the main form, I call Show() on an instance of the window:
AccountInfo Accounts = new AccountInfo();
Accounts.Show();
But all I see is an empty window (not even the right size). Why isn't it opening my window?
I did a simple window and this worked for me. Take it down to just a textbox and see if it works.
public MainWindow()
{
InitializeComponent();
Window1 win1 = new Window1();
win1.Show();
}
The window class name may be different between the xaml definition and the code behind file.
Example
telerik:RadWindow x:Class="MyWindow"
vs
public partial class My_Window : RadWindow
{
public My_Window()
{
InitializeComponent();
}
}
In this case the initializeComponent() call is unrecognized by the compiler