How to disable resizing of a UserControl in WPF - c#

How to:
Disable resizing for this usercontrol. In other words, when the user grabs the corners or the sides of this usercontrol with a mouse, I dont want the user to be able to change the size of the usercontrol?
Or if there is no way to stop resizing then how do I only allow the right side of the usercontrol dragged?
<UserControl x:Class="MyEditor.MyDialog"
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"
d:DesignHeight="152" d:DesignWidth="590" HorizontalContentAlignment="Right" MinWidth="{Binding ElementName=VariableType}" MinHeight="{Binding RelativeSource={RelativeSource Self}}">
<Grid Width="591" Height="147" MinWidth="{Binding ElementName=VariableTypeTextBox}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="137*" />
<ColumnDefinition Width="454*" MinWidth="250" />
</Grid.ColumnDefinitions>
<Button Content="Cancel" Height="23" Margin="0,94,7,0" Name="CancelButton" VerticalAlignment="Top" Click="CancelButton_Click" Grid.Column="1" HorizontalAlignment="Right" Width="75" HorizontalContentAlignment="Center" VerticalContentAlignment="Top" />
<Button Content="Create" Height="23" Margin="0,94,108,0" Name="CreateButton" VerticalAlignment="Top" Click="CreateButton_Click" Grid.Column="1" HorizontalAlignment="Right" Width="75" HorizontalContentAlignment="Center" VerticalContentAlignment="Top" />
<Label Content="Variable Name " Height="28" Margin="0,12,29,0" Name="VariableName" VerticalAlignment="Top" HorizontalAlignment="Right" Width="96" Target="{Binding}" HorizontalContentAlignment="Right" />
<TextBox Height="29" Margin="0,11,7,0" Name="VarNameTextBox" VerticalAlignment="Top" KeyDown="OnKeyDownHandler" MouseLeave="MouseLeaveHandler" LostFocus="LostFocusHandler" Grid.Column="1" HorizontalAlignment="Stretch" />
<Label Content="Variable Type" Height="28" Margin="0,0,29,73" Name="VariableType" VerticalAlignment="Bottom" HorizontalContentAlignment="Right" HorizontalAlignment="Right" Width="96" />
<TextBox Height="23" Margin="0,51,7,0" Name="VariableTypeTextBox" VerticalAlignment="Top" IsReadOnly="True" Background="Silver" Foreground="Black" Grid.Column="1" HorizontalAlignment="Stretch" Width="AUTO" />
</Grid>

You've pasted the XAML for a UserControl, but your question is asking about a Window. So, you will need to place your UserControl inside a Window that is set up to not allow resizing.
A WPF Window has a ResizeMode property, which can be one of the following:
NoResize
CanMinimize
CanResize (default)
CanResizeWithGrip
You will want NoResize.
Example:
<Window x:Class="MyEditor.Views.EditorWindow"
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:views="clr-namespace:MyEditor"
mc:Ignorable="d"
ResizeMode="NoResize"
Title="Editor Window">
<views:MyDialog />
</Window>
Please see the documentation for more details.

Simply set the MinWidth/MaxWidth and MinHeight/MaxHeight properties to your required value.

For Disabling : ResizeMode="CanMinimize"
<Window x:Class="XXXXXX.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:XXXXXXX"
mc:Ignorable="d"
WindowState="Maximized"
ResizeMode="CanMinimize"
Title="Window">

Here is a simple solution:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
((Window)Parent).ResizeMode = ResizeMode.NoResize;
}
Or an attached property on the UserControl if you use the Prism Library:
<prism:Dialog.WindowStyle>
<Style TargetType="Window">
<Setter Property="prism:Dialog.WindowStartupLocation"
Value="CenterScreen" />
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="ShowInTaskbar" Value="False"/>
Setter Property="SizeToContent" Value="WidthAndHeight"/>
</Style>
</prism:Dialog.WindowStyle>

Related

ChangePropertyAction behaviour does not work on Popup with a custom control

Hi i have the following window, it has a button, and when i click on it, it shows a popup that contains some text. When the popup is closed, the behaviour cleans the text inside the popup
<Window
x:Class="WpfTests.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behaviours="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="300"
Height="300"
mc:Ignorable="d">
<StackPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Red"
Orientation="Vertical">
<ToggleButton
x:Name="CustomButton"
Width="40"
Height="40"
Content="Checkbutton" />
<Popup
IsOpen="{Binding ElementName=CustomButton, Path=IsChecked}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=CustomButton}"
StaysOpen="False">
<behaviours:Interaction.Triggers>
<behaviours:EventTrigger EventName="Closed">
<behaviours:ChangePropertyAction
PropertyName="Text"
TargetObject="{Binding ElementName=UrlTextBox}"
Value="" />
</behaviours:EventTrigger>
</behaviours:Interaction.Triggers>
<TextBlock
x:Name="UrlTextBox"
Width="100"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Green"
Foreground="White"
Text="A url" />
</Popup>
</StackPanel>
Now, if i change the child of the popup to a user control like the following:
<Popup
IsOpen="{Binding ElementName=CustomButton, Path=IsChecked}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=CustomButton}"
StaysOpen="False">
<behaviours:Interaction.Triggers>
<behaviours:EventTrigger EventName="Closed">
<behaviours:ChangePropertyAction
PropertyName="Text"
TargetObject="{Binding ElementName=CustomControl, Path=UrlTextBox}"
Value="" />
</behaviours:EventTrigger>
</behaviours:Interaction.Triggers>
<local:CustomControl x:Name="CustomControl" />
</Popup>
CustomControl:
<UserControl
x:Class="WpfTests.CustomControl"
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:local="clr-namespace:WpfTests"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<TextBlock
x:Name="UrlTextBox"
Width="100"
Height="100"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Green"
Foreground="White"
Text="A url" />
The behaviour crashes, because it cannot find the property text and i don't know why.
I know i can do this using code behind, but i would like to do it in the xaml.
Any help would be appreciated
This line isn't going to work
TargetObject="{Binding ElementName=CustomControl, Path=UrlTextBox}"
Because the Path part needs to point to a Property (the TextBlock inside the UserControl is compiled as a public field).
You need to add a line in you UserControl code-behind like this:
public TextBlock UrlText => this.UrlTextBox;
and then in your behaviour change it to this
TargetObject="{Binding ElementName=CustomControl, Path=UrlText}"

Positioning controls - WPF

I am in the process of teaching myself WPF and have an issue that is confusing me. In the XAML below when I open the app the label and image are in the top left part of the window, but when I maximize the window they shift towards the middle. What am I missing that will make the controls keep their relative position?
<Window x:Class="WafLuckyDog.Presentation.Views.ShellWindow"
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:vm="clr-namespace:WafLuckyDog.Applications.ViewModels"
mc:Ignorable="d" Title="{Binding Title}" Icon="{StaticResource ApplicationIcon}" Width="994.273" Height="840"
d:DataContext="{d:DesignInstance vm:ShellViewModel}">
<Window.Background>
<ImageBrush ImageSource="{StaticResource Background}"></ImageBrush>
</Window.Background>
<DockPanel Margin="0,0,-539,0">
<Grid>
<Image Name="Logo" HorizontalAlignment="Left" Margin="0,10,0,669" Width="129"
Source="{StaticResource Logo}" />
<Label Content="Label" HorizontalAlignment="Left" Margin="10,145,0,0" VerticalAlignment="Top" Foreground="AntiqueWhite"/>
</Grid>
</DockPanel>
</Window>
First, you have a DockPanel that has no close tag and is doing nothing, it will give a compile error, so remove it. Also, remove the bottom margin and add a Height and VerticalAlignment properties. The VerticalAlignment and HorizontalAlignment ensures a top right corner anchor.
<Window x:Class="WafLuckyDog.Presentation.Views.ShellWindow"
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:vm="clr-namespace:WafLuckyDog.Applications.ViewModels"
mc:Ignorable="d" Title="{Binding Title}" Icon="{StaticResource ApplicationIcon}" Width="994.273" Height="840"
d:DataContext="{d:DesignInstance vm:ShellViewModel}">
<Window.Background>
<ImageBrush ImageSource="{StaticResource Background}"></ImageBrush>
</Window.Background>
<Grid>
<Image Name="Logo" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Width="129" Height="129"
Source="{StaticResource Logo}" />
<Label Content="Label" HorizontalAlignment="Left" Margin="10,145,0,0" VerticalAlignment="Top" Foreground="AntiqueWhite"/>
</Grid>
</Window>

How to embed WPF Window into another Window and adjust its size via XAML or code

First of all it's my first day using Xaml so this question might be dummy for you, but i totally got lost.
Overview
My technique is that i have MainWindow.xaml and it's split into three areas (using grid columns) the columns width being set automatically.
Based on some actions in the right column, the middle column with show a page let's say Page.xaml that exists in different namespace.
What i'm seeking for
The problem is i need to set the width and height for this page to be equal the middle column width and height as it will fit this area.
Notes
I have very small experience with xaml and binding techniques.
MainWindow.Xaml
<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"
WindowState="Maximized"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Title="MainWindow" d:DesignWidth="1366" d:DesignHeight="768">
<Grid x:Name="MainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.2*" x:Name="LeftColoumn" />
<ColumnDefinition Width="3*" x:Name="CenterColoumn" />
<ColumnDefinition Width=".8*" x:Name="RightColoumn" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="2">
<StackPanel Orientation="Vertical" x:Name="RightStackPanel" Background="LightGray" >
<Border BorderBrush="{x:Null}" Height="50" >
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" FontWeight="SemiBold" FontStyle="Normal" Margin="3" FontSize="20" >Others</TextBlock>
</Border>
<Expander x:Name="Expander1" Header="Others" Margin="0,0,10,0">
<Button Margin="0,0,0,0" Width="{Binding ActualWidth, ElementName=RightStackPanel}" Background="White" Content="Add" Height="50" Click="Button_Click" ></Button>
</Expander>
</StackPanel>
</ScrollViewer>
<Frame Grid.Column="0" x:Name="LeftFrame" Background="LightGray" ></Frame>
<Frame Grid.Column="1" x:Name="CenterFrame" Background="DarkGray" ></Frame>
</Grid></Window>
Other Xaml file
<Page
x:Name="Page"
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"
Title="Any" d:DesignWidth="1364" d:DesignHeight="868"
>
<Grid>
<Frame Background="DarkGray" />
</Grid></Page>
MainWindow.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
Frame middleFrame=CenterColumn;
Otherxaml other=new Otherxaml();
middleFrame.Source = new Uri("OtherxamlPage.xaml", UriKind.RelativeOrAbsolute);
}
Pertinent to your code snippet, you may place the OtherxamlPage.xaml inside the central frame and set the properties of that frame like shown below:
<Frame Grid.Column="1" x:Name="CenterFrame" VerticalAlignment="Stretch" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Source="OtherxamlPage.xaml" Background="DarkGray" />
You can set the Source="OtherxamlPage.xaml" dynamically in event handler, e.g. Button.Click as per your example.
Alternatively, consider the creation of WPF UserControl (re: https://msdn.microsoft.com/en-us/library/cc294992.aspx) instead of that other XAML Window (or Page) and place it directly into the grid cell. In both cases set the content "Stretch" property in order to adjust its size automatically, thus you won't need to specify it in the code.
Hope this may help.

How can set absolute position on stackpanel or grid in xaml WPF

Is it possible to set my StackPanel or Grid to be position absolute like CSS.
In CSS is have property Position of the elements and can set to be relative, absolute and is working good.
In XAML can make Grid, StackPanel to use position absolute.
You have to use Canvas in order to set absolute position in WPF.
In case of buttons in a window, here is a sample :
<Window x:Class="tobedeleted.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"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Button Canvas.Left="10" Canvas.Bottom="20">Bottom left</Button>
</Canvas>
</Window>
The output is :
Feel free to ask if help is needed.
Absolute positioning defeats the purpose of WPF, but I agree, sometimes there is no other way so you have two basic options.
Elements under the root grid
Elements in a canvas that is the same size as the window (as Vasilievski pointed out)
Code example:
<Window x:Class="WpfApplication1.Window3"
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:WpfApplication1"
mc:Ignorable="d"
Title="Window3" Height="300" Width="300">
<Grid>
<Rectangle Fill="Red" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Panel.ZIndex="13"
Margin="12,34"
/>
<Rectangle Fill="Green" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="24,54"
/>
<Canvas>
<Rectangle Canvas.Left="5" Canvas.Top="5" Panel.ZIndex="2" Fill="Yellow" Width="120" Height="30" />
<Rectangle Canvas.Left="25" Canvas.Top="17" Panel.ZIndex="0" Fill="Blue" Width="120" Height="30" />
</Canvas>
</Grid>
</Window>
try this.
<StackPanel>
<Canvas>
<TextBlock Canvas.Left="10" Canvas.Top="6" Text="Choose a value from combobox:" Width="180"/>
<ComboBox Canvas.Left="190" Canvas.Top="4" Width="180"></ComboBox>
</Canvas>
</StackPanel>
RESULT:

C# Strange WPF Combobox Behavior

I have simple window.
This is what happens when I click ComboBox:
List appears in upper left corner of screen instead of under Combobox.
XAML:
<Window x:Class="WpfPortOfTestingCamera.VideoSettings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Video Settings" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" ShowInTaskbar="False" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" SizeToContent="WidthAndHeight" d:DesignHeight="167">
<StackPanel Name="stackPanel1" VerticalAlignment="Top" HorizontalAlignment="Center">
<GroupBox Header="Settings" Name="groupBox1">
<Grid Name="grid1" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80*" />
<ColumnDefinition Width="175*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="Resolution:" Height="28" Name="label1" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Label Content="Framerate:" Height="28" HorizontalAlignment="Left" Margin="0" Name="label2" VerticalAlignment="Center" Grid.Row="1" />
<ComboBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="0" Name="comboBox1" VerticalAlignment="Center" Width="150" SelectionChanged="comboBox1_SelectionChanged" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="0" Name="comboBox2" VerticalAlignment="Center" Width="150" Grid.Column="1" Grid.Row="1" SelectionChanged="comboBox2_SelectionChanged" />
</Grid>
</GroupBox>
<Label Name="labelSelectedSize" Content="Size # FPS" />
<Button Name="button1" Content="Apply" Click="button1_Click" />
</StackPanel>
</Window>
Instead of opening it directly in the Loaded event, just queue another message on the Dispatcher to open it.
I ran into exactly this and just posted an example at WPF ComboBox DropDown part appears in the wrong place which worked for me. The interested reader can go there to peruse my commentary, but here's the snippet (NOTE: WindoBaseLoadedHandler is the "Loaded=" handler specified in the XAML):
protected void WindowBaseLoadedHandler(object sender, RoutedEventArgs e)
{
...non-essential lines of code removed...
if (DataContext != null)
{
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
this.IsEnabled = false;
LoginDlg loginDlg = new LoginDlg();
loginDlg.ShowDialog();
if (!loginDlg.Success)
{
/*-----------------------------------
* Log on failed -- terminate app...
*----------------------------------*/
...termination logic removed...
}
this.IsEnabled = true;
}));
}

Categories