This is my first application with a GUI that I'm building so I might be doing things wrong.
I want to implement some navigation into my app but I don't seem to understand how to do it properly.
Here's the code:
.xaml
<Window x:Class="introducereDAC.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="Divide et Impera" Height="450" Width="800" Background="#FF00000F">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="1*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="5*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Center" TextWrapping="NoWrap" Text="
āIntroducere DEI (curent)" FontFamily="./#Roboto Condensed" Foreground="#505054" Margin="45,0,0,0"/>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="0" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top" Grid.ColumnSpan="2">
<Button Content="Introducere DEI" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="5,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="2" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top" Grid.ColumnSpan="2">
<Button Content="DEI Iterativ" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="5,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="4" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top" Grid.ColumnSpan="2">
<Button Content="Probleme DEI" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="5,0" Click="NavigareProbleme">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="0" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Teorie" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="1" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Avantaje + Dezavantaje" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="2" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Comparatii cu alte metode" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="3" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Cod" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="4" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Complexitate" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<Viewbox Stretch="Uniform" StretchDirection="Both" Grid.Column="5" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Top">
<Button Content="Executie" Width="200" Height="30" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="./#Roboto Condensed" FontWeight="Bold" Margin="10,0">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
<Setter Property="BorderBrush" Value="#77dff1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#77dff1"/>
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="BorderBrush" Value="#77dff1"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Viewbox>
<DockPanel Grid.Row="3" Grid.ColumnSpan="6">
<Frame x:Name="_mainFrame" />
</DockPanel>
</Grid>
</Window>
.xaml.cs
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 introducereDAC
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void NavigareProbleme(object sender, RoutedEventArgs e)
{
_mainFrame.Navigate(new Page1());
}
}
}
As an experiment, I've been trying to do it on the button "Probleme DEI", using Click="NavigareProbleme".
After I double click on the button, my app looks like this:
My goal is to edit that white bar and its buttons however I want, but I don't know how to do it (and I didn't find anything useful on Google), and move it at the top, above the other buttons.
Also, is there any way to make it always be there? (not only after I double click on "Probleme DEI")
Thanks.
I don't recommend to use a Frame. Instead implement a simple custom page/view navigation using data templates. You can follow this examples, if you are interested: C# WPF Page Navigation Class, How do I toggle between pages in a WPF application?.
Do not wrap each control you want to display.
Using a Viewbox to wrap a Button does not make sense. A Button inside a Grid will always stretch to occupy all available space by default. Use a Viewbox to stretch and scale elements that don't have their own resize behavior implemented and require on absolute layout properties, like Path. I doubt that you really want you buttons to stretch freely as this would look very odd.
Wrapping the lonely Frame into a DockPanel also does not make any sense. A DockPanel is a container, that arranges it's child elements relative to each other. It only makes sense to use it with more than a single child. Just add the Frame directly to the Grid. Every redundant Panel and UIElement will cost a unnecessary performance penalty as they have to be measured, arranged and maybe rendered individually (recursively).
Create a style for a control (WPF .NET) - Do not copy and paste styles to reuse them. Define a single Style, assign it a x:Key and add it to a ResourceDictionary e.g, App.xaml. Then reference it using the StaticResource markup (or define the Style as implicit to make it apply to all buttons implicitly):
App.xaml
<ResourceDictionary>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#00000f"/>
<Setter Property="Foreground" Value="#77dff1"/>
...
</Style>
</ResourceDictionary>
Then reference it using StaticResource and the defined key:
<Button Style="{StaticResource ButtonStyle}" />
To customize the navigation bar of the Frame you would have to override the default template. You can visit Frame Styles and Templates to find an example of the original Frame style.
Alternatively hide the original navigation bar (by setting Frame.NavigationUIVisibility) and implement a custom one and use the frame's NavigationService to navigate between its content.
Moving the navigation bar without moving the Frame is not possible. Taking a look at the default template will show you that it is part of the Frame control. You can only move the buttons into a the Page, to make them part of the frame's content.
At this point I have to recommend to implement a custom navigation logic again. It will give you all the flexibility to layout your view you want, as navigation buttons and the actual content host are not part of the same template.
Or hide the original navigation UI and implement your own and locate it where ever you want.
Related
I'm trying to match the Style of a ComboBox I'm creating to a design I have.
I'm unable to connect the Popup border to the Main Border that shows the selected ComboBox item.
I took this ComboBox Template from a site, changed some properties to match the design's style, things were coming along good until I realized I can't connect these 2 aforementioned borders. I'm not exactly sure how we could go about doing it.
I also thought about adding 2 Rows and making the ComboBox Popup Rowspawn but that didn't work either.
Creating a StackOverflow post as I ran out of ideas, any ideas are welcome.
Thank you in advance.
Edit: I was able to use VerticalOffset to move the Popup up, where I want it to be but I can't tuck it underneath the Border I create within the ToggleButton template. Panel.ZIndex usage didn't help either. Still working on a way to accomplish this task.
Design:
My ComboBox:
Here's the part I have an issue with (Along with other parts that I'll address myself later):
Here's my code:
<ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="Border"
Grid.ColumnSpan="2"
CornerRadius="4"
Background="#FFFFFF">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
Opacity="0.29"
BlurRadius="5"/>
</Border.Effect>
</Border>
<Border Grid.Column="0"
CornerRadius="4,0,0,4"
Margin="0,0,1,0"
Background="#FFFFFF"
BorderBrush="LightGray"
BorderThickness="0,0,1.7,0">
</Border>
<Canvas Width="30"
Height="30"
Grid.Column="1"
Margin="9,-18,0,0">
<Canvas.LayoutTransform>
<MatrixTransform Matrix="1,0,0,-1,0,0" />
</Canvas.LayoutTransform>
<Path Data="M131.6625 270.6375A21.1875 21.1875 0 0 0 168.4125 270.6375L296.98125 51.88125C305.55 37.29375 295.25625 18.75 278.60625 18.75H21.45C4.78125 18.75 -5.49375 37.3125 3.075 51.88125L131.6625 270.6375z"
Stroke="{x:Null}"
Fill="#707070"
Stretch="Uniform"
Width="10"
Height="10"
SnapsToDevicePixels="False"
UseLayoutRounding="False"
StrokeThickness="0"
StrokeStartLineCap="flat"
StrokeEndLineCap="flat"
StrokeLineJoin="miter"/>
</Canvas>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
</ControlTemplate>
<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="MinWidth" Value="120"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Foreground" Value="#707070"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid>
<ToggleButton
Name="ToggleButton"
Template="{StaticResource ComboBoxToggleButton}"
Grid.Column="2"
Focusable="false"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press">
</ToggleButton>
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
Margin="15,3,23,3"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="15,3,23,3"
Focusable="True"
Background="#FF3F3F3F"
Foreground="Green"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}"/>
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsDropDownOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Slide">
<Grid Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}"
Margin="15,15,15,15">
<Border
x:Name="DropDownBorder"
Background="White"
BorderThickness="0"
BorderBrush="#888888">
<Border.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
Opacity="0.29"
BlurRadius="5"/>
</Border.Effect>
</Border>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter TargetName="PART_EditableTextBox" Property="Visibility" Value="Visible"/>
<Setter TargetName="ContentSite" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
</Style.Triggers>
</Style>
<!-- SimpleStyles: ComboBoxItem -->
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Foreground" Value="#707070"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true">
<ContentPresenter Margin="8,3,23,3"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have some XAML code template (style) where I couldn't change lable (labelName) text using c# code. Tryed google but cannot find something specific. Looks like there is some small detail that I overlooked.
<Style x:Key="ListBoxItemM" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="brd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<WrapPanel>
<Grid Margin="0,0,0,0">
<Label x:Name="labelName" Content="12345" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="Black" Width="100" FontSize="20" Margin="40,25,0,0"/>
<Label Content="Price" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="Black" Width="60" Height="40" FontSize="12" Margin="180,5,0,0"/>
</Grid>
</WrapPanel>
</RadioButton>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The c# code:
ListBoxItem item = new ListBoxItem();
item.Style = (Style)item.FindResource("ListBoxItemM");
/* Here the label is null, unfortunately */
Label nameLabel = (Label)item.Template.Resources.FindName("labelName");
nameLabel.Content = "98765";
MenuListBox.Items.Add(item);
I have a TextBox input field with a custom style:
<TextBox Style="{StaticResource SettingsTextBoxHint}" KeyDown="textBoxInput_KeyDown" PreviewKeyDown="textBoxInput_PreviewKeyDown" Name="TextBoxInput" Text="{Binding TextBoxInput, Mode=TwoWay}" Tag="{lex:LocText TypeAMessageHere}" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" FontSize="14" HorizontalAlignment="Stretch" VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" Margin="0,0,33,0"/>
To which I added the custom style:
<Style TargetType="{x:Type TextBox}" x:Key="SettingsTextBoxHint" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="White"
Padding="1,2,5,2"
BorderBrush="{StaticResource PrimaryColor}"
ToolTip="{TemplateBinding ToolTip}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
BorderBrush="Transparent"
TextWrapping="{TemplateBinding TextWrapping}"
Panel.ZIndex="2"
FontSize="12">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
Background="Transparent"
BorderBrush="Transparent"
CornerRadius="0">
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<TextBox Margin="0,3,0,0" BorderThickness="0" Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="{StaticResource RobotoRegularFont}" />
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="#cccccc"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="BorderBrush" Value="DarkGray"/>
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="textSource" Property="FocusManager.FocusedElement" Value="{Binding ElementName=textSource}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The point of which is to make the TextBox transparent and to add hint functionality which text is set trough Tag.
Everything works exactly as I want. The problem I have is that I am writing a new functionality in which I need the position of cursor in the TextBox. But SelectionStart or CaretIndex always return 0 value. If I remove my style I get the correct value.
Can anyone tell me what I missed?
The problem is that you are using a TextBox within a TextBox. The user interacts with the inner text box, whose text, caret position, etc. are in no way related to the outer text box.
Let me clean up your style for you:
<Style x:Key="SettingsTextBoxHint"
TargetType="{x:Type TextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderBrush"
Value="{StaticResource PrimaryColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
<TextBlock x:Name="Hint"
Margin="3,1"
Text="{TemplateBinding Tag}"
FontStyle="Italic"
Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
Visibility="Hidden" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter TargetName="Hint" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To find the cursor position within the TextBox, you can use Mouse.GetPosition(your_text_box). To get the caret position within the text, use the CaretIndex property. Note, however, that CaretIndex is *not* a dependency property, so it does not raise change notifications. Thus, you cannot bind to it and expect the binding target to be updated.
I have the following style
<Style x:Key="RoundedBtn" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Image x:Name="image" Source="{Binding ButtonImage, RelativeSource={RelativeSource AncestorType=Button}}" Margin="0,2,0,3" HorizontalAlignment="Left" Width="40" />
<Border BorderBrush="{x:Null}" Height="16" Margin="45,15,0,14" Width="123" HorizontalAlignment="Left">
<TextBlock x:Name="textBlock" Margin="-1" TextWrapping="Wrap" Text="{Binding ButtonText, RelativeSource={RelativeSource AncestorType=Button} }"
FontSize="13"
FontFamily="{DynamicResource Helvetica}" VerticalAlignment="Center" TextDecorations="{x:Null}">
</TextBlock>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#8da0aa"></Setter>
<Setter Property="Foreground" Value="#318EE4"></Setter>
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline">
<!--That Text decoration part doesnt work--></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I apply this style to my "usercontrol" (which is actually a button):
<Button x:Name="btn" x:Class="MyStock.MyButton"
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" Height="45" Width="183" Style="{DynamicResource RoundedBtn}" />
When I generate the project, the "MyButton" appears in my custom controls. But if I drag it on my form and test it, the Text Underline doesnt work.
But If i put a normal button on my form and then apply the RoundedBtn style, it works, why ?
By the way, what I am trying to achieve is to have a button that looks like the left menu buttons on this page
Use TargetName in the Setter:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
The whole style looks like this (I remove irrelevant part for readability)
<Style x:Key="RoundedBtn" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button">
<Grid>
<Border>
<TextBlock x:Name="textBlock" Margin="-1" TextWrapping="Wrap" Text="ABC"
FontSize="13" TextDecorations="{x:Null}">
</TextBlock>
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter TargetName="textBlock" Property="TextBlock.TextDecorations" Value="Underline" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In my WPF application I want to to change borderbrush color for a TextBox when mouse enter, but it does not change color to the one I want, but it change to sky blue (I guess it is standard color).
Here is my XAML code:
<Window x:Class="OnePlayApp.Views.LoginDialog"
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:OnePlayApp.Views"
WindowStyle="None"
ResizeMode="NoResize"
Title="LoginDialog" Height="350" Width="550" Foreground="Black">
<Grid Background="#282828">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24*"/>
<ColumnDefinition Width="43*"/>
<ColumnDefinition Width="43*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="59*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="191*"/>
</Grid.RowDefinitions>
<Image Margin="9,10,173,6" Source="/Resources/logo.png" Grid.ColumnSpan="2"/>
<Label x:Name="AccountName" Content="Account name" Margin="6,10,1,13" Foreground="#FFAFADAD" HorizontalContentAlignment="Right" Grid.Row="1"/>
<Label x:Name="Password" Content="Password
" Margin="6,10,1,13" Foreground="#FFAFADAD" HorizontalContentAlignment="Right" Grid.Row="2"/>
<TextBox x:Name="username" Margin="6,11,15,8" Background="#FF282828" Foreground="White" FontSize="15" Text="Ahsep12015#one.com" FontFamily="Yu Gothic UI Semibold" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" VerticalContentAlignment="Center" BorderThickness="10">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="Green" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<PasswordBox x:Name="password" Margin="6,8,15,13" Background="#FF282828" Password="123456789" FontSize="18" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2"/>
<Button x:Name="LoginBtn" Content="Login" Margin="6,15,15,146" Click="LoginBtn_Click" FontSize="16" FontFamily="Yu Gothic UI Semibold" Foreground="White" Grid.Column="1" Grid.Row="3">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#FFAFADAD"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#79B539"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button x:Name="CancelBtn" Content="Cancel" Margin="6,15,15,146" Click="CancelBtn_Click" FontSize="16" FontFamily="Yu Gothic UI Semibold" Foreground="White" Grid.Column="2" Grid.Row="3">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="#FFAFADAD"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#79B539"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
I had the same issue on Windows 8, and the only way I was able to fix this issue (which appears to be a bug in WPF) was with a ControlTemplate. This is the standard control template for a TextBox as coughed up by Blend. I changed the BorderBrush colors, added it to my global TextBox style, and it works great. There may be a better solution out there, but this is what works for me.
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="Red"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="Orange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>