|
I did find an answer to my question by just modifying a couple of properties and adding a new stack panel. As you can see new stackpanels were added using the attribute Orientation="Horizontal. So the grid now works without adding negtive margin values. Now the only thing I'm working on is trying to add a table sub grid as mentioned above. If anyone has any ideas there that would help. Thanks.
<Window
x:Class="MasterPage.ApplicationInfoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:MasterPage"
Title="Intake 4" Height="900" Width="1000" Background="#FFD9DDE8">
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<StackPanel >
<Border Margin="0, 0, 0, 0" BorderBrush="Black" BorderThickness="1">
<StackPanel Height="133" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<StackPanel>
<Image Source="Images\header.jpg" Stretch="Fill" DockPanel.Dock="Top" Height="47" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<StackPanel Margin="3,0,0,5" HorizontalAlignment="Left">
<Image Source="Images\DSPASS_logo.png" Width="324" Stretch="Fill" DockPanel.Dock="Top" Height="80" />
</StackPanel>
<StackPanel HorizontalAlignment="Right" Margin="400, 0, 0, 0" >
<TextBlock FontSize="15" TextWrapping="WrapWithOverflow" Height="25" Margin="0,60,0,0" >
<Label FontSize="10" HorizontalContentAlignment="Right" HorizontalAlignment="Right" Name="Namelabel" Width="230" FontWeight="Bold" Foreground="#1664A1" Content="Name"/>
</TextBlock>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
<Border Margin="0, 0, 0, 0" BorderBrush="Black" BorderThickness="1">
<StackPanel Background="wHITE" Orientation="Horizontal" Height="358" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1">
<StackPanel>
<Image Source="Images\silhouette.jpg" VerticalAlignment="Top" HorizontalAlignment="Left" Width="320" Stretch="Fill" DockPanel.Dock="Top" Height="360" />
</StackPanel>
<StackPanel>
<TextBlock FontSize="15" HorizontalAlignment="Right" Height="75">
<Label FontSize="35" HorizontalContentAlignment="Left" Name="Namelabel2" Width="640" FontWeight="Bold" Foreground="#1664A1" Content="Name"/>
</TextBlock>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</DockPanel>
</Window>
|
|
|
|
|
After doing a lot of research I found the answer to my problem. See the code below. I now understand a lot more about XAML then I did before. From the code below I now know how to do the upper portion of my page but am lost about how to finish my page.Now my confusion is the bottom part of my page needs to be as set of several vertically tables, two per row, with headers and three columns per table. I think that I need to use grids to do this but still am not sure. If someone could point me in the right direction that would be great.
<Window
x:Class="MasterPage.ApplicationInfoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:MasterPage"
Title="Intake 4" Height="900" Width="1000" Background="#FFD9DDE8">
<StackPanel>
<Border Margin="0, 0, 0, 0" BorderBrush="Black" BorderThickness="1">
<StackPanel Height="133" VerticalAlignment="Top">
<Image Source="Images\header.jpg" Stretch="Fill" Height="47" />
<DockPanel Margin="3,0,0,5">
<Image DockPanel.Dock="Left" Source="Images\DSPASS_logo.png" Width="324" Stretch="Fill" Height="80" />
<Label DockPanel.Dock="Right" FontSize="10" HorizontalContentAlignment="Right" HorizontalAlignment="Right" VerticalAlignment="Bottom" Name="Namelabel" Width="230" FontWeight="Bold" Foreground="#1664A1" Content="Name"/>
</DockPanel>
</StackPanel>
</Border>
<Border Margin="0, 0, 0, 0" BorderBrush="Black" BorderThickness="1">
<DockPanel Background="White" Height="358" VerticalAlignment="Top">
<Image DockPanel.Dock="Left" Source="Images\silhouette.jpg" VerticalAlignment="Top" HorizontalAlignment="Left" Width="320" Stretch="Fill" Height="360" />
<Label DockPanel.Dock="Right" FontSize="35" HorizontalContentAlignment="Left" Name="Namelabel2" Width="640" FontWeight="Bold" Foreground="#1664A1" Content="Name"/>
</DockPanel>
</Border>
</StackPanel>
</Window>
|
|
|
|
|
I'm creating a List type of control[^].
The ListBox's DataTemplate will be an Expander.
Each Expander will have UserControls added to it from the code behind at runtime. How do I ensure that the control is added to the correct Expander?
Thanks
If it's not broken, fix it until it is
|
|
|
|
|
Track each Expander's control reference.
|
|
|
|
|
I have a XAML window that the layout is done using a main grid. The problem is when the browser is resized the controls in the second and third columns move to the right and the window's layout is no longer correct. I have pasted the XAML below. I think the layout of a WPF window should be grid based with all controls residing in the window's master grid. Is this the proper layout design for WPF or is there a different recommended layout pattern? Also, I find myself having to use negative value in margins. This confuses me greatly as well.
<Window x:Class="MasterPage.Intake1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:MasterPage.View"
Title="Intake 1" Height="900" Width="1000" Background="#FFD9DDE8" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35*"/>
<RowDefinition Height="45*"/>
<RowDefinition Height="190*"/>
<RowDefinition Height="275*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500*"/>
<ColumnDefinition Width="300*"/>
<ColumnDefinition Width="250*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0">
<Image Source="Images\header.jpg" Height="47" Margin="0,0,0,0" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Grid.Column="0" Height="80" Width="350" Grid.ColumnSpan="1" Grid.Row="1" Margin="0,-23,0,0">
<Image Source="Images\DSPASS_logo.png" Stretch="Fill" DockPanel.Dock="Top" Height="70" />
</StackPanel>
<StackPanel Grid.Column="4" Grid.Row="1" Grid.ColumnSpan="1" Margin="0,0,0,0">
<TextBlock FontSize="15" Margin="0,0,0,0" Height="25" Width="300" TextWrapping="WrapWithOverflow">
<Label FontSize="10" Name="Namelabel" Width="250" FontWeight="Bold" Foreground="#1664A1" Content="Welcome to DS PASS:"/>
</TextBlock>
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" Margin="10,10,0,0" Height="290" Width="975" VerticalAlignment="Top" Grid.ColumnSpan="3" Grid.RowSpan="1">
<Label Height="36" FontSize="16" Content="Post Identification" Background="#FF014E7E" FontWeight="Bold" Foreground="White" Margin="-5,0,-18,0"/>
<StackPanel x:Name="_wordLength" Orientation="Horizontal" Margin="235,0,200,0">
<TextBlock Height="20" x:Name="ApplicantType_TextBlock" Text="Applicant Type" Width="110" Margin="5" TextAlignment="Right"/>
<ComboBox Height="25" x:Name="textBoxWordLength" Width="400" Margin="10,5"/>
</StackPanel>
<StackPanel x:Name="_integerWordLength" Orientation="Horizontal" Margin="235,0,200,0">
<TextBlock Height="20" x:Name="textBlockIntegerWordLength" Text="Person Type" Width="110" Margin="5" TextAlignment="Right"/>
<ComboBox Height="25" x:Name="textBoxIntegerWordLength" Width="400" Margin="10,5"/>
</StackPanel>
<StackPanel x:Name="_Post" Orientation="Horizontal" Margin="235,0,200,20">
<TextBlock Height="20" x:Name="Post_TextBlock" Text="Post" Width="110" Margin="5" TextAlignment="Right"/>
<ComboBox Height="25" x:Name="Post_TextBox" Width="400" Margin="10,5"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="3" HorizontalAlignment="Left" Height="130" Margin="15,-120,0,0" VerticalAlignment="Top" Grid.ColumnSpan="3" >
<Label Height="36" FontSize="16" Content="Applicant Employment" Background="#FF004A78" FontWeight="Bold" Foreground="White" Margin="-5,0,-18,0"/>
<StackPanel x:Name="_max1" Orientation="Vertical" Margin="1,0,355,0">
<TextBlock Height="20" x:Name="maxTextBlock1" Text="Employee ID" Width="100" Foreground="Black" Margin="0,15,459,5" TextAlignment="Right"/>
<TextBox Height="25" x:Name="maxTextBox1" Width="400" Margin="0,-5,90,25"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="3" Orientation="Vertical" HorizontalAlignment="Left" Height="330" Margin="0,10,0,0" VerticalAlignment="Top" Width="965" Grid.RowSpan="2">
<Label Height="36" FontSize="16" Content="English Version of Name" Background="#FF005183" Grid.Row="4" FontWeight="Bold" Margin="10,10,0,0" Foreground="White" Padding="4,5,5,5"/>
<StackPanel x:Name="_LastName" Orientation="Vertical">
<TextBlock Height="20" x:Name="LastName_TextBlock" Text="Last Name/Surname" Margin="55,5,459,5" TextAlignment="Left"/>
<TextBox Height="25" x:Name="LastName_TextBox" Width="500" Margin="55,5,459,5"/>
</StackPanel>
<StackPanel x:Name="_FirstName" Orientation="Vertical">
<TextBlock Height="20" x:Name="FirstName_TextBlock" Text="First Name" Margin="55,0,459,0" TextAlignment="Left"/>
<TextBox Height="25" x:Name="FirstName_TextBox" Width="500" Margin="55,0,459,0"/>
</StackPanel>
<StackPanel x:Name="_MiddleName" Orientation="Vertical">
<TextBlock Height="20" x:Name="MiddleName_TextBlock" Text="Middle Name" Margin="55,5,459,5" TextAlignment="Left"/>
<TextBox Height="25" x:Name="MiddleName_TextBox" Width="500" Margin="55,5,459,5"/>
</StackPanel>
<StackPanel x:Name="_ExtendedName" Orientation="Vertical">
<TextBlock Height="20" x:Name="ExtendedName_TextBlock" Text="Extended name (Tribal, Jr., III, etc.)" Margin="55,5,372,5" TextAlignment="Left"/>
<TextBox Height="25" x:Name="Extended_TextBox" Width="500" Margin="55,5,459,5"/>
</StackPanel>
</StackPanel>
<StackPanel Grid.RowSpan="4" Grid.Column="4" HorizontalAlignment="Left" Height="230" Margin="-250,400,0,0" Width="480" Grid.ColumnSpan="1">
<StackPanel x:Name="_Aliases" Orientation="Vertical" Margin="-15,0,0,0" Height="144">
<TextBlock Height="20" x:Name="Aliases_TextBlock" Text="Aliases" Margin="40,-5,0,5" TextAlignment="Left"/>
<TextBox Height="25" x:Name="Aliases_TextBox" Width="500" Margin="43,5"/>
<TextBox Height="25" x:Name="Aliases_TextBox1" Width="500" Margin="43,5"/>
<TextBox Height="25" x:Name="Aliases_TextBox2" Width="500" Margin="43,5"/>
</StackPanel>
</StackPanel>
<Label HorizontalAlignment="Left" Margin="4,400,0,0" Grid.Row="4" VerticalAlignment="Top" Background="#FF52BB52" Grid.ColumnSpan="3" Width="983" Height="36">
</Label>
<Button Content="Save Draft" Grid.Column="1" HorizontalAlignment="Left" Margin="150,408,0,0" Grid.Row="5" VerticalAlignment="Top" Width="125" />
<Button x:Name="ContinueButton_Page2" Content="Continue" Grid.Column="1" Width="125" Grid.Row="5" VerticalAlignment="Top" Margin="200,408,0,0" Grid.ColumnSpan="2" Click="btnContinue_Click"/>
</Grid>
</Window>
modified 17-Jul-16 10:51am.
|
|
|
|
|
WPF works for you when your "view" is laid out in a logical manner; yours is not; it is particularly obvious if you look at your XAML in the "document outline" and "design" windows.
StackPanels are hard to control; it's easier / more intuitive using "Grids within Grids".
You should not be altering "heights" and "margins" (from their defaults) to affect positioning; the "styles" (i.e. height, width, etc.) of the individual controls should drive the (automatic) layout.
Start by removing the height and width of the window and look at the properties that relate to its content; e.g. StartupLocation; SizeToContent; WindowState; etc.
|
|
|
|
|
So, I basically took the reordering from Josh Smith:
Drag and Drop Items in a WPF ListView[^]
All I wanted to do now was to draw a line where the new item was inserted, with an arrow. Like the old WinForms style behavior:
Manual reordering of items inside a ListView[^]
The line under was easy to achieve, all I had to was to alter the Style:
<Style x:Key="ItemContStyle" TargetType="ListViewItem">
<Style.Resources>
<LinearGradientBrush x:Key="MouseOverBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#22000000" Offset="0" />
<GradientStop Color="#44000000" Offset="0.4" />
<GradientStop Color="#55000000" Offset="0.6" />
<GradientStop Color="#33000000" Offset="0.9" />
<GradientStop Color="#22000000" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
</Style.Resources>
<Setter Property="Padding" Value="0,4" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--
<Setter Property="Border.BorderThickness" Value="0,0,0,0.5" />
<Setter Property="Border.BorderBrush" Value="Transparent"/>
<!--
<Style.Triggers>
<Trigger Property="jas:ListViewItemDragState.IsBeingDragged" Value="True">
<Setter Property="FontWeight" Value="DemiBold" />
</Trigger>
<Trigger Property="jas:ListViewItemDragState.IsUnderDragCursor" Value="True">
<Setter Property="Border.BorderThickness" Value="0,0,0,0.5" />
<Setter Property="Border.BorderBrush" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
SO I looked at the ControlTemplate for the ListViewItems:
ListViewItem ControlTemplate Example[^]
But as soon as I started to add the ControlTemplate Design the correct behavior stopped:
<Style x:Key="ItemContStyle" TargetType="ListViewItem">
<Style.Resources>
<LinearGradientBrush x:Key="MouseOverBrush" StartPoint="0.5, 0" EndPoint="0.5, 1">
<GradientStop Color="#22000000" Offset="0" />
<GradientStop Color="#44000000" Offset="0.4" />
<GradientStop Color="#55000000" Offset="0.6" />
<GradientStop Color="#33000000" Offset="0.9" />
<GradientStop Color="#22000000" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Grid>
<Polygon
x:Name="poly_PART"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Stroke="Red"
Fill="Red"
StrokeThickness="2"
Points="0,1 0,-1 1,0"
Margin="0,0,0,0"
Width="10"
Height="10"
Stretch="Fill"
/>
<ContentPresenter
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Padding" Value="0,4" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--
<Setter Property="Border.BorderThickness" Value="0,0,0,0.5" />
<Setter Property="Border.BorderBrush" Value="Transparent"/>
<!--
<Style.Triggers>
<Trigger Property="jas:ListViewItemDragState.IsBeingDragged" Value="True">
<Setter Property="FontWeight" Value="DemiBold" />
</Trigger>
<Trigger Property="jas:ListViewItemDragState.IsUnderDragCursor" Value="True">
<!--
<Setter Property="Border.BorderThickness" Value="0,0,0,0.5" />
<Setter Property="Border.BorderBrush" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
How do I fix this issue?
|
|
|
|
|
Here is a common way of having a ViewModel's property with the INotifyPropertyChanged interface:
string text;
public string Text
{
get { return text; }
set
{
if (value != text)
{
text = value;
NotifyPropertyChanged(nameof(Text));
}
}
}
This occupies one line for the member variable and twelve lines for the property.
In my ViewModel I have many properties and the code is getting very huge due to each property need the above body to include the NotifyPropertyChanged method and a member varible.
I prefer my properties to be defined in this way:
public string Text { get; set; }
That property's body is just one line and I don't need to define a member variable.
But I cannot find out how to call the NotifyPropertyChanged method.
Is there a solution to short the body of the property and still have the call to the NotifyPropertyChanged method?
For instance:
* Having a property without the need of a member variable.
* Define the property as close as possible to: public string Text { get; set; } .
* Having the call to the NotifyPropertyChanged in the setter body.
Best regards,
/Steffe
|
|
|
|
|
Mc_Topaz wrote: Is there a solution to short the body of the property and still have the call to the NotifyPropertyChanged method? No.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
|
No.
However you can make your declaration easier by using Code Snippets[^].
Here is my MVVM property snippet
="1.0"="utf-8"
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
<Title>SnippetFile1</Title>
<Author>Lloyd</Author>
<Description>INotifyPropertChanged property</Description>
<HelpUrl>
</HelpUrl>
<Shortcut>propn</Shortcut>
</Header>
<Snippet>
<Declarations>
<Object Editable="true">
<ID>Type</ID>
<ToolTip>Type</ToolTip>
<Default>object</Default>
<Function>
</Function>
<Type>
</Type>
</Object>
<Literal Editable="true">
<ID>Property</ID>
<ToolTip>Property</ToolTip>
<Default>Property</Default>
<Function>
</Function>
</Literal>
</Declarations>
<Code Language="csharp"><![CDATA[</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
|
|
|
|
|
There is a way to do this, but it requires an extra bit of build infrastructure. You can, relatively easily, use an AOP (aspect-oriented programming) solution like PostSharp[^] or you could use a Roslyn analyzer/generator[^].
This space for rent
|
|
|
|
|
The "notify patterns" used in this case are "standard"; but not necessarily THE ONLY way.
If performance is not any issue, and UI updates are localized (usually), then simply issue a "NotifyPropertyChanged(string.Empty)" and the "UI engine" will "refresh" ALL output fields.
Used judiciously, it can make more sense to do "notifications" from your main logic than within a "setter"; particularly when it comes to real-time updates that reference multiple "outputs" for computing other outputs.
As an alternative, one can "queue" names of properties that were changed, remove duplicates, then pump them through a notify call; if that fits.
You can then leave the properties as automatic gets and setters.
Benchmark.
|
|
|
|
|
I usually do this (took the code from somwhere but I cant remember the referance):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
public abstract class NotifierBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then I simply call it like this:
private string m_Name ="";
public string Name
{
get { return m_Name; }
set
{
SetProperty(ref m_Name, value);
}
}
I just have a custom snippet to deal with the proeprty coding.
|
|
|
|
|
I applaud your construction but to save 1 if statement and 1 line of code. You ROI is minimal
I use a snippet for the entire property structure and a region surrounding all the properties. Saving half a dozen lines of code per property is just not that high on my todo list.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I have a wonderful WPF grid that I downloaded from a Codeproject article below. The problem is the grid doesn't do column sorting. Has anyone modified this grid WPF grid for column sorting? Article: DataView Paging in WPF[^]
|
|
|
|
|
Even though this article is 6 years old, the best place to ask this would be in the comments at the end of the article. That way the author would be notified of your question, and any additional discussion that follows would remain associated with the article for others to find in the future.
"Fairy tales do not tell children the dragons exist. Children already know that dragons exist. Fairy tales tell children the dragons can be killed."
- G.K. Chesterton
|
|
|
|
|
You are correct. The comments after article do expand on the article itself. Unfortunately nothing about column sorting. I really want to use this for my project but it requires sorting. Any ideas?
|
|
|
|
|
|
[REDACTED]
Found this[^]
If it's not broken, fix it until it is
modified 30-Jun-16 15:02pm.
|
|
|
|
|
I am starting a new WPF project that's framework is going to be some sort of a tabbed view dashboard. In ASP I would use a master page with a tab control and a content page for each view. I am new to XAML and was hoping that someone knew of a basic article with example code to get me started. If anyone can point me in the right direction that would be great.
-- modified 28-Jun-16 18:47pm.
|
|
|
|
|
You're going to have to read this[^] a few times but it should give you a fair idea about how to pull together an application that suits your needs.
This space for rent
|
|
|
|
|
Sacha Barber[^] has written a load of excellent articles on WPF, from beginner to advanced framework.
|
|
|
|
|
In WPF:
There is a "main window" that would correspond to your "master page".
You can add a WPF "Tab Control" (to the window) that can contain multiple "Tab Item" controls.
The "content" for each tab can be added directly (e.g. as Text Blocks (labels), Text Boxes, Buttons, etc.); however, one generally creates "User Controls" to package UI elements into a view / content page which would then be added to a tab (as a child).
WPF uses "styles" in a way that is similar to CSS in order to propagate styling throughout the visual tree (of UI elements).
|
|
|
|
|
The article below makes doing WPF views just like MVC:
<a href="http://www.codeproject.com/Tips/678020/Master-page-in-WPF">Master page in WPF?</a>[<a href="http://www.codeproject.com/Tips/678020/Master-page-in-WPF" target="_blank" title="New Window">^</a>]
|
|
|
|
|