We are about to move to WPF and are currently working on a templated window.
After hours of reading and following tutorials on CodeProject and StackOverflow I am struggling with a, what I believe rather simple, problem in regards of transparency.
When I run the app, there is no "content" in my window.
I have my Style defined in Generic.xaml, which is located in the Themes folder.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MTApp"
x:Class="MTApp.Themes.Generic">
<ControlTemplate x:Key="WindowTemplate" TargetType="{x:Type Window}">
<Grid x:Name="WindowRoot">
<Border x:Name="WindowFrame">
<Grid Margin="0" VerticalAlignment="Top" MouseDown="Window_MouseDown">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="75*"/>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="30" />
<RowDefinition Height="35" />
<RowDefinition Height="35" />
<RowDefinition Height="140*" />
</Grid.RowDefinitions>
<Frame x:Name="background" Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" Background="#ddd" BorderThickness="0 0 0 1" BorderBrush="#c9c9c9"/>
<Label x:Name="windowTitle" Grid.ColumnSpan="2" Content="Title Bar" VerticalAlignment="Center" Foreground="#393939" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" FontFamily="Segoe UI Regular" FontSize="12"/>
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="14"/>
<ColumnDefinition Width="13"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="10" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Button x:Name="minimizeBtn" Content="" Background="#39b54a" BorderThickness="0" Grid.Row="1" Grid.Column="1" Margin="3 0 0 0" Click="minimizeBtn_Click"/>
<Button x:Name="maximizeBtn" Content="" Background="#f8be3f" BorderThickness="0" Grid.Row="1" Grid.Column="2" Margin="3 0 0 0" Click="maximizeBtn_Click"/>
<Button x:Name="quitBtn" Content="" Background="#f84646" BorderThickness="0" Click="quitBtn_Click" Grid.Row="1" Grid.Column="3" Margin="3 0 0 0"/>
</Grid>
</Grid>
</Border>
</Grid>
</ControlTemplate>
<Style x:Key="SkinWindowStyle" TargetType="Window">
<Setter Property="WindowStyle" Value="None" />
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="Background" Value="#ffffff" />
<Setter Property="Opacity" Value="100" />
<Setter Property="ResizeMode" Value="CanResize" />
<Setter Property="Width" Value="600" />
<Setter Property="Height" Value="300" />
<Setter Property="Template" Value="{StaticResource WindowTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding WindowState}" Value="Maximized">
</DataTrigger>
</Style.Triggers>
</Style>
It defines "WindowStyle" and "AllowsTransparency" as seen in many tutorials, if I set "AllowsTransparancy" to False I will get a border full black window.
As you can see from the style already, I want to have the background white. But All I get is an "empty" window. I wanted to force some witdh onto it, as you can see from the other setter items.
My MainWindow.xaml, which is the actuall app looks like this:
<Window x:Class="MTApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Style="{DynamicResource SkinWindowStyle}"
Background="White"
Height="300"
Width="350"
>
<Grid Background="White" Height="100" Width="200">
<TextBlock Text="Test" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Background="White"/>
</Grid>
It uses the style defined in Generic.xaml, which all works fine. Sure, the Background, Height and Width cannot overwrite the style's properties, because its hard coded, but still, the Grid should be shown as well as the text box. But none of these appear.
Lastly, the Generic.xaml.cs:
using System;
using System.Windows;
using System.Windows.Input;
namespace MTApp.Themes
{
public partial class Generic : ResourceDictionary
{
public Generic()
{
InitializeComponent();
}
/**
* Header Buttons Events
**/
private void minimizeBtn_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.WindowState = WindowState.Minimized;
}
private void maximizeBtn_Click(object sender, RoutedEventArgs e)
{
if (Application.Current.MainWindow.WindowState == WindowState.Maximized)
{
Application.Current.MainWindow.WindowState = WindowState.Normal;
}
else
{
Application.Current.MainWindow.WindowState = WindowState.Maximized;
}
}
private void quitBtn_Click(object sender, RoutedEventArgs e)
{
Window.GetWindow(((FrameworkElement)e.Source)).Close();
}
/**
* Window Events
**/
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
Window.GetWindow(((FrameworkElement)e.Source)).DragMove();
}
}
}
}
Mind you, its derived from ResourceDictionary, I could not get it working from "Window" as seen in the 5 tutorials available online...
So here my question, why is nothing shown below my custom content ? Do I need to specify a certain canvas on which we can then put our controls for each window ? Think login window, options window, message/confirm window. They should all share the same style, and hence we want to have the window templated.
To allow adding controls to the window, you need to add a ContentPresenter control to the ControlTemplate. Add the following to the template code:
<ControlTemplate x:Key="WindowTemplate" TargetType="{x:Type Window}">
<Grid x:Name="WindowRoot">
<Border x:Name="WindowFrame">
<Grid Margin="0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
... header controls ...
<ContentPresenter Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="1"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
Of course, the ContentPresenter's Grid.Row and Grid.Column settings need to be adapted, depending on where you'd like the window content to be inserted.
Related
I'm creating a form in WPF. The form has TextBoxes with TextBlocks to their left. A screenshot with GridLines is below:
I want it to look like this (forgive the MS Paint style):
The problem is: the text boxes are really small unless I set the HorizontalAlignment to Stretch, but if I do that, I can't align them to the left. How do I get the Grid containing TextBlock/TextBox to align to the left and make the TextBox fill all available space?
It's trivially easy if I hardcode widths, but that obviously won't work with resizing. I've tried playing with Stack and Dock Panels to hold the Grids with no luck.
I can't use HorizontalAlignment=Stretch, MaxWidth, and Left aligned at the same time? because there is no other control that is the width of the space I am trying to fill.
I also can't use How to get controls in WPF to fill available space? because nothing in my xaml has HorizontalContentAllignment. I tried wrapping stuff in ContentControls and using an ItemsControl to force it with no luck.
The xaml for the form is below. Note, this xaml is for the control that is under the 'Create' header and to the right of the 3 buttons.
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Left hand side content goes here-->
<DockPanel Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
Margin="20,0,0,0">
<Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Input Name:"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
<Grid ShowGridLines="True" DockPanel.Dock="Top" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition SharedSizeGroup="TextBoxColumn"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Input Name:"
HorizontalAlignment="Right" VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</DockPanel>
</Grid>
The FormTextBox style is:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="TextBox"
x:Key="FormTextBox">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border CornerRadius="10"
Background="{StaticResource InputBrush}">
<Grid>
<Rectangle StrokeThickness="1"/>
<TextBox Margin="1"
Text="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0"
Background="Transparent"
VerticalContentAlignment="Center"
Padding="5"
Foreground="{StaticResource TextBrush}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It rounds the corners, changes the background color, and removes the dotted line that shows up if it was selected before you alt-tabbed out and back into the application.
You indicate that this is the desired layout:
There are a few problems with your current code. First, using a DockPanel to host the TextBlock/TextBox pairs, and second, no control has Grid.IsSharedSizeScope=true set on it. You also have defined a shared size for the text box column when in reality you just want it to take up all the available space.
Here is some code that achieves the desired layout:
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--Left hand side content goes here-->
<StackPanel Orientation="Vertical" Grid.Column="1"
Grid.RowSpan="2"
Margin="20,0,0,0"
Grid.IsSharedSizeScope="True" >
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Grid.Column" Value="0"/>
<Setter Property="Text" Value="Input Name:"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</StackPanel.Resources>
<Border BorderBrush="Blue" BorderThickness="5">
<Grid ShowGridLines="True" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock/>
<TextBox Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</Border>
<Border BorderBrush="Red" BorderThickness="5">
<Grid ShowGridLines="True" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="TextBlockColumn"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock/>
<TextBox Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource FormTextBox}"
Margin="5,0,5,0"/>
</Grid>
</Border>
</StackPanel>
</Grid>
This code produces:
In reality though, if you're going for maximum usability, you'll want to create your own control for the TextBlock/TextBox, and then you could just put it in an ItemsControl of some kind for dynamic content.
Since some people can't be bothered to click on a link, here's all ~80 lines of XAML code for the window...
<Window x:Class="TollLicenser.Views.LicenseView"
x:Name="wdw"
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:TollLicenser.Views"
mc:Ignorable="d"
Title="License View" Height="300" Width="300"
xmlns:vm="clr-namespace:TollLicenser.ViewModels"
d:DataContext="{d:DesignInstance vm:LicenseViewModel}"
SizeToContent="WidthAndHeight"
Margin="8">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Button.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Shadows.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ToggleButton.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource MaterialDesignTextBox}">
<Setter Property="Margin" Value="0 8 8 8" />
</Style>
<Style TargetType="{x:Type DatePicker}">
<Setter Property="Margin" Value="0 8 8 8" />
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Margin" Value="0 8 8 8" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="8" />
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid FocusManager.FocusedElement="{Binding ElementName=CountryCode}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Style="{StaticResource MaterialDesignHeadlineTextBlock}">
Managing a License
</TextBlock>
<Label Grid.Row="1" Grid.Column="0">Country Code</Label>
<TextBox Grid.Row="1" Grid.Column="1" Name="CountryCode" Text="{Binding CountryCode}"/>
<Label Grid.Row="2" Grid.Column="0">Plaza Name</Label>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding TollPlazaName}"/>
<Label Grid.Row="3" Grid.Column="0">Start Date</Label>
<DatePicker Grid.Row="3" Grid.Column="1" SelectedDate="{Binding StartDate}"/>
<Label Grid.Row="4" Grid.Column="0">End Date</Label>
<DatePicker Grid.Row="4" Grid.Column="1" SelectedDate="{Binding EndDate}"/>
<Label Grid.Row="5" Grid.Column="0">Max Users</Label>
<TextBox Grid.Row="5" Grid.Column="1" Text="{Binding MaxUsers}"/>
<GridSplitter Grid.Row="6" Height="5" />
<Button Grid.Row="7" Grid.Column="0" Content="Save" Margin="8" IsEnabled="True" IsDefault="True"
Command="{Binding SaveLicenseCommand}" CommandParameter="{Binding ElementName=wdw}" />
</Grid>
</Window>
Basically the problem is that the damn button (seen below) is disabled even from the time the window opens...
This seems to bind correctly to the ViewModel.
Only things in the viewmodel that have anything really to do with the button is the command and the method it executes as below:
public ICommand SaveLicenseCommand => new AwaitableDelegateCommand<Window>(SaveLicense);
private async Task SaveLicense(Window wdw)
{
_model.Id = Id;
_model.CountryCode = Encryption.Encrypt(CountryCode);
_model.EndDate = Encryption.Encrypt(EndDate.ToString());
_model.MaxUsers = Encryption.Encrypt(MaxUsers.ToString());
_model.StartDate = Encryption.Encrypt(StartDate.ToString());
_model.TollPlazaName = Encryption.Encrypt(TollPlazaName);
// LYTODO Post the model to the web service.
if (_model.Id != 0)
{
// Editing a license.
await _apiHelper.PutLicenseAsync(_model);
await _licenses.Load(); // Reload licenses with the updated item.
}
else
{
// Adding a license.
await _apiHelper.PostLicenseAsync(_model);
}
wdw.Close();
}
I don't have the faintest idea why the button is disabled or what other information to provide so please comment if there's more that you need and I will include it.
Why is the window opening with the button disabled?
I have a problem with my ListBox. I have written several DataTemplates which I use in a ListBox. Each one of these contains a grid and may contain a nested ListBox depending on the item.
My problem is: The height of these nested ListBoxes seem to be different to the root ListBox's height. Additionally it seems, that there is sometimes one pixel margin to the element above.
Has someone encountered this problem, too and maybe solved it?
XAML-Code:
<!-- Template for SubData-Items -->
<DataTemplate x:Key="DataTemplate">
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999" Background="Violet">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
<Line Grid.ColumnSpan="999" Stroke="Black" X1="0" X2="{Binding ElementName=baseGrid, Path=ActualWidth, Mode=OneWay}" Y1="0" Y2="0" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
<!-- Template for Items -->
<DataTemplate x:Key="GroupDataTemplate">
<Grid Grid.ColumnSpan="999" Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Gantt, Path=GridRowHeight}" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
</Grid>
<Grid x:Name="expandedGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999">
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="0,0,2,0"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
</Grid>
</Grid>
</DataTemplate>
<!-- Grid with ListBox -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="Row0" Height="34"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" Width="25" />
<ColumnDefinition x:Name="Col1" Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999" ItemsSource="{Binding ItemSource, Mode=OneWay}"
ItemTemplate="{StaticResource GroupDataTemplate}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto"
ScrollViewer.CanContentScroll="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
FontSize="10" />
</Grid>
qqbenq gave a very nice solution . Here is another way to do it.
the control templates of ListBox and ListBoxItem has padding inside their borders. Thankfully ListBoxItem border's padding can be control by a style like so:
<Style
TargetType="ListBoxItem">
<Setter
Property="Padding"
Value="0" />
</Style>
but unfortunately for the ListBox , you will have to override the default template with all of its details to change its internal border's hard-coded padding like this:
<Style
TargetType="ListBox">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="0"
SnapsToDevicePixels="true">
<ScrollViewer
Focusable="false"
Padding="{TemplateBinding Padding}">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger
Property="IsEnabled"
Value="false">
<Setter
Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger
Property="IsGrouping"
Value="true">
<Setter
Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
One last note : remove the Margin that you added inside your xaml.
Solution complete
Add a Margin="-2,0,0,0" and a Padding="-1" to your "LBMaGruppen" named ListBox.
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="-2,0,0,0" Padding="-1"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
Also, the "root" element's height is binded to {Binding ElementName=Gantt, Path=GridRowHeight}, while the "sub" element's height to {Binding ElementName=Row0, Path=Height}, so this must cause the difference.
It seems that you have auto height set on all your ListBox. You could try setting the height to a specific size. EDIT: I see you already have ScrollViewer settings. I think setting the height of the box to a specific size instead of auto will do what you want.
As to the padding between elements see the ListBox.ItemContainerSyle which should allow you to set the margin between elements.
I have a disabled TextBox in a Grid.
The Grid has a BackgroundColor and I want the TextBox to just show some Text.
How can I get the Background of a disabled TextBox to be Transparent?
Here is what I have tried:
<UserControl x:Class="MyProject.Views.TextBoxView"
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"
d:DesignHeight="435"
d:DesignWidth="589"
FontFamily="Arial"
mc:Ignorable="d">
<Grid Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.Resources>
<Style x:Key="TextboxStyle_uniqueName" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="Control.IsEnabled" Value="False">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="36" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="20*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0"
Grid.Column="0"
Width="Auto"
Height="Auto"
Margin="0"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
BorderThickness="0"
FontFamily="Courier New"
FontSize="30"
Foreground="Black"
IsEnabled="False"
IsReadOnly="True"
IsTabStop="False"
Style="{StaticResource TextboxStyle_uniqueName}"
Text="BLAHBLAHBLAH" />
</Grid>
</Grid>
</UserControl>
If the Textbox is enabled, everything is okay and setting the Background works.
But as soon I disable it, I can no longer set the Background correctly.
Thought about some hack of Binding IsEnabled, so that the Background is set before.
-EDIT-
Strangly enough using TextBlock solves the issue. But I definitly have no style in the project that sets a background different from the default for TextBox.
I have problems with a .NET 4 application using Bing Maps with custom pushpins. The performance is very bad on zooming or moving the map. I'm using a ObservableCollection which has a data-binding to Bing Maps. Everytime the map changes it is being checked which pushpins are in the map section. The collection will be re-filled and finally a NotifyCollectionChangedEvent is being fired which makes the map draw the pushpins.
<bingMap:MapItemsControl ItemsSource="{Binding Locations}">
<bingMap:MapItemsControl.ItemTemplate>
<DataTemplate>
<bingMap:Pushpin Location="{Binding Coordinates}" Height="Auto" Width="Auto" PositionOrigin="BottomCenter"
Template="{StaticResource PushpinControlTemplateLoc}">
</bingMap:Pushpin>
</DataTemplate>
</bingMap:MapItemsControl.ItemTemplate>
</bingMap:MapItemsControl >
I made some researches with a performance profiler: The InitializeComponent() method of my custom pushpin class needs an average time of 25% to 35%!
There are usually between 10 and 25 custom pushpins displayed on the map. If I reduce the amount of data bindings it becomes a little bit faster, but still not fast enough.
I've already tested out to declare all the brushes as freezed static resources but the drawing still runs very slow.
<SolidColorBrush x:Key="SolidColorBrushUnknownMsg" Color="Gray" ice:Freeze="True" xmlns:ice="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options" />
I tried to use the Microsoft default pushpins <bingMap:Pushpin Location="{Binding Coordinates}"/> which was much faster. So there must be something wrong in my usage or implementation of my custom pushpin.
Here's the rest of my code:
Custom pushpin class (only auto-generated code):
public partial class MyPushpin: System.Windows.Controls.Grid
{
public MyPushpin()
{
InitializeComponent();
}
}
Custom pushpin XAML code:
<Grid x:Class="Test.MyPushpin"
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">
<Grid.Resources>
<Style BasedOn="{StaticResource DataTextBlock}" x:Key="test1" TargetType="TextBlock">
<Setter Property="Background" Value="{StaticResource SolidColorBrushErrorMsg}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TextLine1, Mode=OneWay}" Value="0">
<Setter Property="Background" Value="{StaticResource BackgroundImage}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Border CornerRadius="20" BorderBrush="White" Padding="7" Opacity="0.8" Width="120" Height="100" Background="{StaticResource BackgroundImage}">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="test2" Foreground="Black" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TextLine2, StringFormat=N1,Mode=OneWay}" Style="{StaticResource DataTextBlock}" />
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding objCurrentPower.sUnit,Mode=OneWay}" Foreground="Black" />
<!--three more lines of textblocks with data bindings -->
</Grid>
</Border>
Why does my custom pushpin need so much performance?
Problem solved: Instead of using a separate class and xaml and referencing to them it's better to use a ControlTemplate for the custom pushpins in the class the actually contains the Bing Map:
<ControlTemplate x:Key="CutomPushpinTemplate" TargetType="bingMap:Pushpin">
<Border CornerRadius="15" BorderBrush="White" Padding="7" Opacity="0.8" Width="120" Height="90" Background="{StaticResource Bgr_enercon}">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="16" />
<RowDefinition Height="16" />
<RowDefinition Height="16" />
<RowDefinition Height="16" />
<RowDefinition Height="16" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45" />
<ColumnDefinition Width="32" />
<ColumnDefinition Width="23" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="test2" Foreground="Black" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TextLine2, StringFormat=N1,Mode=OneWay}" Style="{StaticResource DataTextBlock}" />
<TextBlock Grid.Row="0" Grid.Column="2" Text="{Binding objCurrentPower.sUnit,Mode=OneWay}" Foreground="Black" />
<!--three more lines of textblocks with data bindings -->
</Grid>
</Border>
</ControlTemplate>
This template is used for all pushpins of the Bing Map this way:
<bingMap:MapItemsControl ItemsSource="{Binding Locations}">
<bingMap:MapItemsControl.ItemTemplate>
<DataTemplate>
<bingMap:Pushpin Location="{Binding objCoordinates}" Height="Auto" Width="Auto" PositionOrigin="BottomCenter" Template="{StaticResource CutomPushpinTemplate}">
</bingMap:Pushpin>
</DataTemplate>
</bingMap:MapItemsControl.ItemTemplate>
Doing it that way is much faster. The performance profiler shows that the programm now does not spend so much time for instantiating the custom pushpins.
Here is the xaml code which shows how it was implemented before (slow):
<ControlTemplate x:Key="PushpinControlTemplateLoc" TargetType="bingMap:Pushpin" >
<Test.MyPushpin />
</ControlTemplate>