Alright, so I am pretty new to WPF and I've tasked myself with a pretty hard challenge. I'm trying to make a program for the company I work for. I've already designed the Login Window and now, I'd like to design the dashboard.
Here is a screenshot of the login Window, with it's XAML below:
Login window
<Window x:Class="Programme_de_gestion.LoginWindow"
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:Programme_de_gestion"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="380"
AllowsTransparency="True" Background="Transparent"
WindowStyle="None" ResizeMode="NoResize"
MouseDown="Window_MouseDown">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border CornerRadius="10" Grid.RowSpan="2">
<!--Création du style de la fenêtre-->
<Border.Background>
<!--Les gradientstop servent à sélectionner
les couleurs du background de la fenêtre.
Je me suis servis du site:
https://htmlcolorcodes.com/fr/-->
<LinearGradientBrush>
<GradientStop Color="#918886 " Offset="0.0"/>
<GradientStop Color="#EBE7E6 " Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<StackPanel VerticalAlignment="Center">
<!--Image logo à insérer en début de fenêtre.
J'ai pris le logo de JPG ICI:
https://secureservercdn.net/45.40.148.147/vzq.777.myftpupload.com/wp-content/themes/swoo/images/logo1.png-->
<Image Source="Images\logoJPG.png" Width="200"/>
<!--À décider si on garde le texteblock sous le logo ou non-->
<TextBlock Text="Connection"
FontWeight="Light"
FontFamily="Helvetica"
FontSize="22"
Foreground="white"
HorizontalAlignment="Center"/>
</StackPanel>
<!-- StackPanel contenant toute la section du bas-->
<StackPanel Grid.Row="1">
<!--StackPanel pour la section du nom d'utilisateur et Icone-->
<StackPanel Orientation="Horizontal">
<!--Zone de texte pour le login-->
<TextBox FontFamily="Helvetica"
FontWeight="Light"
Text="Username"
FontSize=" 20 "
HorizontalAlignment="Center"
Foreground ="White"
Background="Transparent"
BorderThickness="0"
Width="235"
HorizontalContentAlignment="Left"
Opacity="0.5"
Height="25"
Margin="63,0,0,0"/>
<!--Icone de compte-->
<iconPacks:PackIconMaterial Kind="Account"
Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</StackPanel>
<!--Border pour faire plus chic-->
<Border Width="250"
Height="2"
Opacity="0.5"
Background="white"/>
<!--StackPanel pour la section password-->
<StackPanel Orientation="Horizontal"
Margin="0,20,0,0">
<!--Champ d'entrée du mot de passe-->
<PasswordBox FontFamily="Helvetica"
FontWeight="Light"
Password="Password"
FontSize=" 20 "
HorizontalAlignment="Center"
Foreground ="White"
Background="Transparent"
BorderThickness="0"
Width="235"
HorizontalContentAlignment="Left"
Opacity="0.5"
Height="25"
Margin="63,0,0,0"/>
<!--Icone pour le mot de passe-->
<iconPacks:PackIconMaterial Kind="Lock"
Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</StackPanel>
<!--Bordure pour faire plus chic-->
<Border Width="250"
Height="2"
Opacity="0.5"
Background="white"/>
<TextBlock Text="MOT DE PASSE OUBLIÉ?"
Margin="0,5,0,0"
FontWeight="Light"
FontFamily="Helvetica"
FontSize="8"
Foreground="white"
HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" Margin="0,30,0,0">
<Button Width="100" Height="40" Content="LOGIN"
HorizontalAlignment="Center"
Margin="60,0,0,0"
Name="btnLogin"
Click="btnLogin_Click" Cursor="Hand"/>
<Button Width="100" Height="40" Content="FERMER"
HorizontalAlignment="Center"
Margin="60,0,0,0"
Name="btnFermer"
Click="btnFermer_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</Grid>
</Window>
After the LoginWindow, a MainWindowAppears:
MainWindow
The section on the Right is a View in which I intend to house my dashboard as a Window. When a different element is selected on the left, the window displayed in the view will change.
The first Issue I have is with the buttons. I made a custom control for the button in the Login Window, which is in ModernButton.xaml.
For the Dashboard, I'd like to use a nuget package called Material Design In XAML. Now, when I add the Nuget package and add the ressource dictionnaries to my ResourceDictionary.MergedDictionaries, the button style of my login window is changed to the one provided by the Material design package. How can I conserve the style of the button I defined in ModernButton.XAML
Also, I'm not so sure about the window that changes in the view section on the right. If it's something that wouldn't work, do you have other solutions for me.
Sorry for the long post, let me know if you need more of my source code or if my explanations are unclear, English isn't my mother tongue.
Edit:
Here is the code in the ModernButton.XAML:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="ModernButton">
<Setter Property="Foreground" Value="white"/>
<Setter Property="FontFamily" Value="Helvetica"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background ="{TemplateBinding Background}" CornerRadius="20"
BorderThickness="2"
BorderBrush="White">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Opacity" Value="0.4"/>
<Setter Property="Foreground" Value="DeepSkyBlue"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
And here is the code in the App.XAML:
<Application x:Class="Programme_de_gestion.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Programme_de_gestion"
StartupUri="LoginWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ModernButton.xaml"/>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
As for the Button style, you simply forgot to specify the style which you defined in ModernButton.xaml. It is why that style is overridden by another style included in Material design package.
To fix this, set Style property of the Button.
<Button Width="100" Height="40" Content="LOGIN"
HorizontalAlignment="Center"
Margin="60,0,0,0"
Name="btnLogin"
Cursor="Hand"
Style="{StaticResource ModernButton}"/>
As for the application structure, I think this is matter of typical master-detail pattern and you can find a variety of samples for it.
Related
I am using the WPF chart toolkit (System.Windows.Controls.DataVisualization.Charting). All stylings are in the XAML and I only bound the data to chart from my ViewModel. Everything looks alright for the first time I click on a button to show the columnseries. When I click on the button for the second time, the chart becomes bigger/corrupted; It shows only part of the graph.
The graph is drawn for the first time:
And button clicked for the second time:
The code I am using is as below:
<dvc:Chart Cursor="Cross"
Background="#FFFFFCF2"
Title="{Binding Title}"
Height="410"
Width="750"
VerticalAlignment="Top"
Name="ChartContainer">
<dvc:Chart.Series>
<dvc:ColumnSeries ItemsSource="{Binding ChartData,UpdateSourceTrigger=PropertyChanged}"
IndependentValueBinding="{Binding Path= Key}"
DependentValueBinding="{Binding Path= Value}"
Name="SummariesChart"
Margin="0,0,0,0"
IsManipulationEnabled="False">
<dvc:ColumnSeries.DataPointStyle>
<Style TargetType="dvc:ColumnDataPoint">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dvc:ColumnDataPoint">
<Grid>
<Rectangle Fill="{TemplateBinding Background}"
Stroke="Black" />
<Grid Margin="0,0, 0, 0"
HorizontalAlignment="Center"
VerticalAlignment="Top">
<TextBlock Text="{TemplateBinding FormattedDependentValue}"
Margin="2" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</dvc:ColumnSeries.DataPointStyle>
</dvc:ColumnSeries >
</dvc:Chart.Series >
<dvc:Chart.Axes>
<dvc:LinearAxis Orientation="X"
Title="{Binding XTitle}"
Interval="1"
Location="Bottom"
ShowGridLines="True" />
<dvc:LinearAxis Orientation="Y"
Title="{Binding YTitle}"
ShowGridLines="True"
Location="Left" />
</dvc:Chart.Axes>
</dvc:Chart>
Also, to give you complete idea, I used a style on top of the page as follow:
<Style TargetType="dvc:Chart">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dvc:Chart">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<dv:Title Content="{TemplateBinding Title}"
Style="{TemplateBinding TitleStyle}"
Margin="1" />
<Grid Grid.Row="1"
Margin="1,0,1,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<primitives:EdgePanel x:Name="ChartArea">
<Grid Canvas.ZIndex="-1"
Style="{TemplateBinding PlotAreaStyle}" />
<Border Canvas.ZIndex="10"
BorderBrush="#FF919191"
BorderThickness="1" />
</primitives:EdgePanel>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BarDataPointStyle"
TargetType="{x:Type dvc:BarSeries}">
<Setter Property="Background"
Value="Blue"></Setter>
<Setter Property="Opacity"
Value="0" />
</Style>
When I remove <dvc:Chart.Axes> block, it works correctly consistently. But I need X-axe and Y-axes descriptions existing in this code block. Do you know how I can tackle this problem? I appreciate your help.
I found a way to resolve the issue. But still, I am skeptical that something is wrong with the styling or something.
I added Minimum = 0 and Maximum in LinearAxis tag. I bounded Maximum to a variable in my ViewModel. I got the length of the array and added one to the maximum variable(MaxNumberInXAxes).
<dvc:LinearAxis Orientation="X"
Title="{Binding XTitle}" I
nterval="{Binding XAxisInterval}"
Location="Bottom"
ShowGridLines="True"
AllowDrop="False"
Minimum="0"
Maximum="{Binding MaxNumberInXAxes}"/>
The graph becomes something like this:
With this piece of XAML:
<Window.Resources>
<Rectangle x:Key="rectangle" x:Shared="False" Width="20" Height="8" Fill="Red" />
</Window.Resources>
<StaticResource x:Name="r1" ResourceKey="rectangle" />
<StaticResource x:Name="r2" ResourceKey="rectangle" />
it is possible to assign a value to say, Margin property, to each instance independently by code:
r1.Margin = 2;
r2.Margin = 5;
Is it possible to do it directly in XAML? I tried:
<StaticResource ResourceKey="rectangle" Margin="3"/>
but Margin is not a property of StaticResource...
Rephrasing after the XY problem sensor fired (appropriately)!
I want to draw rectangles with exactly the same properties except one, e.g. the margin or the color, in order to be able to change the shared properties centrally and still be able to provide specific properties in XAML. Can I use a resource like in my attempt?
Adding my exact need and code as suggested by comments
My exact need is to show the effect of setting different properties to some rectangle, i.e. changing Rectangle.RenderTransformOrigin and Rectangle.RenderTransform to compare effects. It's indeed to learn WPF, not for a production application. At the moment, I use a style (rotated) as I wasn't able to use a resource (this is the reason of my question above).
<Window x:Class="Test.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:Test"
mc:Ignorable="d"
Title="Transform Center" Height="400" Width="600">
<Window.Resources>
<Style x:Key="title" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Margin" Value="0,0,0,10" />
</Style>
<Style x:Key="rotated" TargetType="Rectangle">
<Setter Property="Width" Value="201" />
<Setter Property="Height" Value="81" />
<Setter Property="Fill" Value="CadetBlue"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style x:Key="fixed" TargetType="Rectangle">
<Setter Property="Width" Value="30" />
<Setter Property="Height" Value="30" />
<Setter Property="Fill" Value="Indigo" />
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Window.Resources>
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}" />
</StackPanel>
<TextBlock Grid.Row="0" Grid.Column="0"
Style="{StaticResource title}" Text="No rotation" />
<StackPanel Grid.Row="0" Grid.Column="1" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransformOrigin>.5,.5</Rectangle.RenderTransformOrigin>
<Rectangle.RenderTransform>
<RotateTransform Angle="20" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="0" Grid.Column="1"
Style="{StaticResource title}"
Text="RenderTransformOrigin" />
<StackPanel Grid.Row="1" Grid.Column="0" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransform>
<RotateTransform Angle="20" CenterX="100" CenterY="40" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="0"
Style="{StaticResource title}"
Text="RotateTransform Center" />
<!-- The center coordinates relative to the Rectangle are the sum
of both center coordinates, i.e. .5 + .5 = 1 (bottom-right corner) -->
<StackPanel Grid.Row="1" Grid.Column="1" Background="Beige" Margin="5">
<Rectangle Style="{StaticResource fixed}" />
<Rectangle Style="{StaticResource rotated}">
<Rectangle.RenderTransformOrigin>.5,.5</Rectangle.RenderTransformOrigin>
<Rectangle.RenderTransform>
<RotateTransform Angle="20" CenterX="100" CenterY="40" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="1"
Style="{StaticResource title}"
Text="Both" />
</Grid>
</Window>
Does XAML allows to change a property of a resource when it is instantiated with <StaticResource>
Short answer: No.
The StaticResource markup extension simply references a resource based on a key. It can't change any properties of the resolved resource. You will have to set the properties of the resolved resource itself by for example casting the target property of the resource to a Rectangle.
I want to draw rectangles with exactly the same properties except one, e.g. the margin or the color
That sounds like a style to me. In WPF, there are usually several different ways to accomplish the same thing, and this is no exception.
it seems setting up a view-model is a bit oversized
Maybe. Maybe not. It's hard to say, as there aren't any other details in your question. That said, given the problem statement above, I'd agree it's certainly not necessary, and absent any other requirements, I don't see anything to be gained by using view models.
Even so, here's a code example that shows three different ways, two of which are based on view models and templates:
<Window x:Class="TestSO58683029RectStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="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:l="clr-namespace:TestSO58683029RectStyle"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<l:MainViewModel>
<l:MainViewModel.Rectangle1>
<l:RectangleViewModel Margin="2"/>
</l:MainViewModel.Rectangle1>
<l:MainViewModel.Rectangle2>
<l:RectangleViewModel Margin="5"/>
</l:MainViewModel.Rectangle2>
</l:MainViewModel>
</Window.DataContext>
<Window.Resources>
<p:Style TargetType="Rectangle">
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="8"/>
<Setter Property="Fill" Value="Red"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</p:Style>
<DataTemplate DataType="{x:Type l:RectangleViewModel}">
<Rectangle Width="20" Height="8" Fill="Red" HorizontalAlignment="Left" Margin="{Binding Margin}"/>
</DataTemplate>
<x:Array x:Key="rectangleArray1" Type="{x:Type l:RectangleViewModel}">
<l:RectangleViewModel Margin="2"/>
<l:RectangleViewModel Margin="5"/>
</x:Array>
</Window.Resources>
<StackPanel>
<!-- Uses style -->
<Rectangle/>
<Rectangle Margin="2"/>
<Rectangle Margin="5"/>
<!-- Uses view models, individual properties -->
<ContentControl Content="{Binding Rectangle1}"/>
<ContentControl Content="{Binding Rectangle2}"/>
<!-- Uses view models, collection -->
<ItemsControl ItemsSource="{StaticResource rectangleArray1}"/>
</StackPanel>
</Window>
The view model approaches rely on these classes (they don't implement INotifyPropertyChanged, because there's no need in this simple example):
class RectangleViewModel
{
public Thickness Margin { get; set; }
}
class MainViewModel
{
public RectangleViewModel Rectangle1 { get; set; }
public RectangleViewModel Rectangle2 { get; set; }
}
As you can see, in the case of the style-based approach, a single <Style/> element in the resource dictionary can be used to define the default values for any properties you like. Then you can explicitly use a <Rectangle/> element where you want it in the content of your window, setting any other property explicitly. You can even override properties that were set in the style, if that's needed for any reason.
Note that in the above, the data template explicitly sets its property values. But you can actually combine the two techniques, by referring to the style resource when you declare the template, like so:
<DataTemplate DataType="{x:Type l:RectangleViewModel}">
<Rectangle Margin="{Binding Margin}" Style="{StaticResource ResourceKey={x:Type Rectangle}}"/>
</DataTemplate>
As noted in the comments, declaring concrete UI elements as resources is generally the wrong way to do something in WPF. I hesitate to say it's always wrong, but I would say it's almost always wrong. Concrete UI elements should be declared as actual content in the XAML, with styles used to provide default formatting for those elements. Otherwise you should be using templates, and allow WPF to create the UI elements as needed, based on the template you provide.
I have a WPF application. When I press the exit button, I want to see the box like this:
The box name is Risultati. This works, but I want the all WPF application is disable and I can see a light gray how the modal dialog.
This is the code that I use to create my box, Risutlati:
<UserControl x:Class="ContattoOculare.RiepilogoEsercizio"
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="342" d:DesignWidth="520">
<Grid Margin="0,0,0,0" Height="342" Width="520">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="35" />
<RowDefinition Height="40" />
<RowDefinition Height="100" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.Background>
<ImageBrush x:Name="backgroudCarta" ImageSource="./Resources/Esci_dal_gioco_Maschera.png"/>
</Grid.Background>
<!--INTESTAZIONE-->
<Grid Grid.Row="0" Margin="0,20,0,0" >
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Label Content="Risultati" VerticalAlignment="Bottom" HorizontalAlignment="Center"
FontSize="30" FontFamily="./Font/#Roboto-Bold" Foreground="White"/>
</Grid>
<Grid Grid.Row="1" Margin="0,0,0,14">
<Label Content="Contatto Oculare" VerticalAlignment="Top" HorizontalAlignment="Center"
FontSize="18" FontFamily="./Font/#Roboto-Bold" Foreground="White" Margin="190,-12,184,0"/>
</Grid>
</Grid>
<!--FINE INTESTAZIONE-->
<!--PRIMA RIGA-->
<Grid Grid.Row="1">
<Label Content="Tempo" FontSize="22"
FontFamily="./Font/#Roboto-Bold" Foreground="Gray" HorizontalAlignment="Center"/>
</Grid>
<!--FINE PRIMA RIGA-->
<!--SECONDA RIGA-->
<Grid Grid.Row="2" Margin="0,-12,0,0">
<Label x:Name="labelTempo" Content="0 sec" FontSize="25" FontWeight="Bold"
FontFamily="./Font/#Roboto-Bold" Foreground="Gray" HorizontalAlignment="Center"/>
</Grid>
<!--FINE SECONDA RIGA-->
<!--TERZA RIGA-->
<Grid Grid.Row="3" Margin="50,0,50,0">
<TextBox x:Name="textDescrizione" VerticalAlignment="Top" FontSize="25"
FontFamily="Calibri" Foreground="Gray"
TextWrapping="Wrap" AcceptsReturn="True" Height="100" />
</Grid>
<!--FINE TERZA RIGA-->
<!--QUARTA RIGA-->
<Grid Grid.Row="4" HorizontalAlignment="Center" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Height="Auto" Width="Auto" HorizontalAlignment="Center"
Grid.Column="0" >
<Image Width="206" Height="46"
HorizontalAlignment="Center" VerticalAlignment="Bottom"
x:Name="save">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="./Resources/Tasto_Uscita gioco_Salva_Roll_ON.png"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Roll_OFF.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Roboto-Bold"
FontSize="20" Foreground="White">Salva</Label>
</Grid>
<Grid Height="Auto" Width="Auto" HorizontalAlignment="Center"
Grid.Column="1" >
<Image Width="206" Height="46"
HorizontalAlignment="Center" VerticalAlignment="Bottom"
x:Name="stop">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Salva_Roll_OFF.png"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Source" Value="./Resources/Tasto_Uscita_gioco_Roll_OFF.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Roboto-Bold"
FontSize="20" Foreground="White">Annulla</Label>
</Grid>
</Grid>
<!--FINE QUARTA RIGA-->
</Grid>
</UserControl>
How can I do this?
For any WPF window, I normally will implement a mask over its content, something like:
<Window>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibility"/>
</Window.Resources>
<Grid>
<Grid>
<!--your window content-->
</Grid>
<!--this is your mask, give it a semi-transparent color-->
<Grid Background="#65000000" Visibility="{Binding IsModalDialogActived, Converter={StaticResource BooleanToVisibility}}"/>
<Grid>
<!--your dialog-->
</Grid>
</Grid>
</Window>
So that you can set the mask to Visible when your show the modal dialogue, and the mask will cast a shadow over the interface and prevent any user interactions with your application.
I would extend the Window class rather than the UserControl class. Then, call ShowDialog to show up your box. All other windows in the application will be disabled. That's a true (WPF) modal dialog, loosely coupled and reusable across your application.
Keep in mind:
Use AllowsTransparency="True" to allow semi-transparent colors for the Background.
Use WindowStyle="None" to remove the borders.
Use WindowState="Maximized" to occupy all available space.
Set the HorizontalAlignment, VerticalAlignment, Width, Height and Margin properties in your main Grid to place your box where desired.
I have implemented IDataErrorInfo in my ViewModel to return a string if the text box has error.
public string this[string columnName]
{
get { return "Error-- This is a long error message - sd"; }
}
But this error message goes behind the other control on the UI as shown below.
Below is the xaml:
<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="600">
<Window.Resources>
<ControlTemplate x:Key="validationTemplateNew">
<DockPanel LastChildFill="True">
<TextBlock Name="ErrorText" DockPanel.Dock="Bottom" Foreground="White" Background="Red"
FontSize="12" Padding="2" FontFamily="Trebuchet MS"
Margin="5,5,0,0"
TextWrapping="Wrap"
Text="{Binding [0].ErrorContent}" ></TextBlock>
<AdornedElementPlaceholder Name="ErrorTextBox" />
</DockPanel>
</ControlTemplate>
<Style x:Key="ValidationStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BitmapEffect">
<Setter.Value>
<BitmapEffectGroup>
<OuterGlowBitmapEffect GlowColor="Red" GlowSize="3" Noise="0.6"></OuterGlowBitmapEffect>
</BitmapEffectGroup>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ItemsControl Name="ItemCtrl">
<AdornerDecorator>
<TextBox
FontSize="11"
Margin="10"
Width="250"
VerticalAlignment="Center"
Text="{Binding Path=StrText, ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource validationTemplateNew}"
Style="{StaticResource ValidationStyle}"
>
</TextBox>
</AdornerDecorator>
<TextBox Width="250" Text="ASDFASFASDFASDFASDFASDFASDF"/>
<TextBox Width="250" Text="ASDFASFASDFASDFASDFASDFASDF"/>
<TextBox Width="250" Text="ASDFASFASDFASDFASDFASDFASDF"/>
<TextBox Width="250" Text="ASDFASFASDFASDFASDFASDFASDF"/>
<TextBox Width="250" Text="ASDFASFASDFASDFASDFASDFASDF"/>
</ItemsControl>
</Grid>
</Window>
Please let me know how to use AdornerDecorator such that the error message overlaps the other controls and doesn't go behind.
My application is such that if I don't use AdornerDecorator, the error message is not displayed at all.
Adding Grid.ZIndex on the AdornerDecorator should be enough
<Grid>
<ItemsControl Name="ItemCtrl">
<AdornerDecorator Grid.ZIndex="1">
I have WPF Form which has many buttons with the same code. Appearance of all buttons must be the same
For example, code for one of these buttons
<Button x:Name="btnAddRelative" Width="120" Click="btnAddRelative_Click" >
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" Add Relative" Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
How can I create one style and use it for all my buttons. All buttons has the same png image, only their text different. How can I do this.
I tried to do this with Style object in Resource Section:
<UserControl.Resources>
<Style TargetType="Button" x:Key="AddStyle">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" " Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
But this code not work. Can any body know how can I do this?
If the image is fix you can hard-code it in the style, and use the Content property of Button bin to the Content of TextBox
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel
Orientation="Horizontal">
<!--<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>-->
<TextBlock
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Content}"
Height="20"
VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
just try this
<Window.Resources>
<Style TargetType="Button"
x:Key="AddStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal">
<Image Height="26"
Width="20"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="/WpfApplication33;component/Images/MoveLeft.png" />
</Image.Source>
</Image>
<TextBlock Text ="{TemplateBinding Content}"
Height="20"
/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource AddStyle}"
Height="25" Width="100"
Content="Button1"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button22"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2233"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2332"></Button>
</StackPanel>
</Grid>
Note: Use ContentPresenter instead of TextBlock if you have to display anything other than flat text
Try changing your style as follows
<UserControl.Resources>
<Style
TargetType="Button"
x:Key="AddStyle">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel
Orientation="Horizontal">
<Image
Height="26"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage
UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock
Text=" "
Height="20"
VerticalAlignment="Center" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
[Edit inspired by comment]
You could create a new UserControl, lets call it AddButtonContent containing your Stackpanel and such, then include that within your button, like so:
<Button>
<local:AddButtonContent
ButtonText="Testing, one, two, three" />
</Button>
You'll need to add a xmlns reference called local (or whatever you'd like to call it) to the UserControl with all of the buttons.
The codebehind portion of your AddButtonContent UserControl will need the following code, and you'll need to name your TextBlock (I used testText for this example).
public static DependencyProperty ButtonTextProperty =
DependencyProperty.Register("ButtonText",
typeof(string),
typeof(AddButtonContent),
new PropertyMetadata("", onTextChangedCallback));
public string ButtonText
{
get { return (string)GetValue(ButtonTextProperty); }
set
{
SetValue(ButtonTextProperty, value);
}
}
static void onTextChangedCallback(
DependencyObject dobj,
DependencyPropertyChangedEventArgs args)
{
AddButtonContent abc = dobj as AddButtonContent;
abc.testText.Text = args.NewValue.ToString();
}