Forums

Border thickness and resizing windows
Last Post 19 Oct 2017 04:16 AM by James Haywood. 5 Replies.
Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
James HaywoodUser is Offline
New Member
New Member
Posts:5


--
30 Sep 2017 04:52 AM
    I'm having a couple problems with windows and borders. I'm using WindowViewModel and a ControlTemplate to create a simple reusable window with a border. Whenever I want to display some text, I set the lines of text I want, calculate the width and height the window needs to be to fit the text, set the width and height of the window, and then show it.

    Here's the xaml for the window...
    <ControlTemplate x:Key="BorderWindowTemplate">
    <Border Background="{Binding Background}">
    <Border
    Margin="{Binding Margin}"
    BorderBrush="{Binding BorderBrush}"
    BorderThickness="{Binding BorderThickness}">
    <ContentPresenter Content="{Binding}" />
    </Border>
    </Border>
    </ControlTemplate>

    One problem is that if I don't set a MinWidth and MinHeight in the WindowViewModel constructor, the inner border doesn't show up at all. I'm guessing the thickness is set at construction based on the window's dimensions, except that in my case it doesn't have a size at that point. So I'm assuming it's setting the thickness to zero.

    And that brings me to the second problem. Setting the minimum dimensions does give me the inner border like I expect, except that as I resize the window, the thickness also resizes. If I create a long vertical window, the top and bottom border lines will be stretched vertically. And the same goes for horizontal boxes, the sides get stretched in that case.

    Like I said, I'm guessing you don't recalculate the border thicknesses when the window size changes. So it just ends up stretching. Is this something that can be fixed, or is there a workaround I can implement?

    One last thing, it would be great if you supported the SizeToContent property of WPF windows so that I didn't have to manually calculate it each time.
    Filip DušekUser is Offline
    Advanced Member
    Advanced Member
    Posts:676


    --
    01 Oct 2017 09:38 PM
    so you want to make floating window right?
    James HaywoodUser is Offline
    New Member
    New Member
    Posts:5


    --
    09 Oct 2017 03:06 PM
    Yes, I'm making a floating window where I control the position and size every time it's opened.
    Filip DušekUser is Offline
    Advanced Member
    Advanced Member
    Posts:676


    --
    14 Oct 2017 09:16 AM
    I use control template and data template like this:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:vm="clr-namespace:EmptyKeys.UserInterface.Debug;assembly=EmptyKeys.UserInterface.Debug">
    
        <ControlTemplate x:Key="Debug_WindowTemplate">
            <ContentPresenter Content="{Binding}" />
        </ControlTemplate>
        
        <DataTemplate DataType="{x:Type vm:DebugViewModel}" >
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="1.5*"/>
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
    
                <Grid Background="{Binding ToolbarBackground}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
    
                    <ToggleButton Name="pickElem" Content="Pick an Element" Margin="5" IsChecked="{Binding IsPickModeEnabled}" Command="{Binding PickCommand}" TabIndex="100" />
                    <ToggleButton Name="showGuides" Content="Show Guides" ToolTip="Show Margin and Padding guides" IsChecked="{Binding IsDrawMarginPaddingEnabled}" Margin="5" Grid.Column="1" TabIndex="101"/>
                    <TextBox Name="searchInput" Text="{Binding Path=SearchText}" Grid.Column="2" TabIndex="102">
                        <TextBox.InputBindings>
                            <KeyBinding Key="Enter" Command="{Binding SearchCommand}" />
                        </TextBox.InputBindings>
                    </TextBox>
                    <TextBlock Name="searchHint" Text="Search Visual Tree..." Visibility="{Binding Path=IsSearchInputEmpty}" 
                               Grid.Column="2" IsHitTestVisible="False" Margin="3,0,0,0" VerticalAlignment="Center" />
                    <Button Name="search" Margin="5" Grid.Column="3" Height="24" Width="24" IsEnabled="{Binding IsSearchButtonEnabled}" Command="{Binding SearchCommand}"
                            ToolTip="Search" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" TabIndex="103">
                        <Button.Resources>
                            <SolidColorBrush x:Key="ButtonBackgroundDisableBrush" Color="#505050" />
                        </Button.Resources>
                        <Grid Margin="2">
                            <Ellipse Width="12" Height="12" Stroke="White" StrokeThickness="2" HorizontalAlignment="Right" VerticalAlignment="Top"/>
                            <Line X1="2" Y1="16" X2="9" Y2="9" Stroke="White" StrokeThickness="2" />
                        </Grid>
                    </Button>
                </Grid>
                
                <TextBlock Text="Visual Tree" Grid.Row="1" />
    
                <TreeView Name="visualTree" ItemsSource="{Binding Mode=OneWay, Path=TreeElements}" Grid.Row="2" TabIndex="104" />
    
                <Border Background="Black" BorderBrush="Gray" BorderThickness="1" Visibility="{Binding IsSearchModeEnabled}" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <TextBlock Text="Searching..." Margin="5"/>
                </Border>
    
                <TabControl Grid.Row="3">
                    <TabItem Header="Mouse" HorizontalContentAlignment="Stretch">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
    
                            <TextBlock Text="Mouse Position:" />
                            <TextBlock Text="{Binding Mode=OneWay, Path=MousePosition}" Grid.Column="1" />
    
                            <TextBlock Text="Mouse Over:" Grid.Row="1"/>
                            <TextBlock Text="{Binding Mode=OneWay, Path=MouseOverElement.Name}" Grid.Column="1" Grid.Row="1"/>
    
                            <TextBlock Text="Mouse Over Type:" Grid.Row="2" />
                            <TextBlock Text="{Binding Mode=OneWay, Path=MouseOverElementTypeName}" Grid.Row="2" Grid.Column="1"/>
    
                            <TextBlock Text="Mouse Over Template Parent:" Grid.Row="3" />
                            <TextBlock Text="{Binding Mode=OneWay, Path=MouseOverTemplateParentName}" Grid.Row="3" Grid.Column="1"/>
    
                            <TextBlock Text="Focused:" Grid.Row="4" />
                            <TextBlock Text="{Binding Mode=OneWay, Path=FocusedElementName}" Grid.Row="4" Grid.Column="1"/>
    
                            <TextBlock Text="Focused Type:" Grid.Row="5" />
                            <TextBlock Text="{Binding Mode=OneWay, Path=FocusedElementTypeName}" Grid.Row="5" Grid.Column="1"/>
    
                        </Grid>
                    </TabItem>
    
                    <TabItem Header="Bindings">
                        <Grid>
                            <DataGrid Name="bindingsGrid" ItemsSource="{Binding Bindings}" AutoGenerateColumns="False">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="Source" Binding="{Binding Source}" />
                                    <DataGridTextColumn Header="Mode" Binding="{Binding Mode}" />
                                    <DataGridTextColumn Header="Target" Binding="{Binding Target}" />
                                </DataGrid.Columns>
                            </DataGrid>
                        </Grid>
                    </TabItem>
    
                    <TabItem Header="Values">
                        <Grid>
                            <DataGrid Name="valuesGrid" ItemsSource="{Binding Values}" AutoGenerateColumns="False">
                                <DataGrid.Columns>
                                    <DataGridTextColumn Header="Property" Binding="{Binding Property}" />
                                    <DataGridTextColumn Header="Value" Binding="{Binding Value}" />
                                </DataGrid.Columns>
                            </DataGrid>
                        </Grid>
                    </TabItem>
    
                </TabControl>
    
            </Grid>
        </DataTemplate>
    
        <DataTemplate DataType="{x:Type vm:TreeElement}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="2"  Text="{Binding Mode=OneWay, Path=Name }" />
                <TextBlock Margin="2"  Text="{Binding Mode=OneWay, Path=TypeName, StringFormat=[{0}]}" />
            </StackPanel>
        </DataTemplate>
    
    </ResourceDictionary>
    



    James HaywoodUser is Offline
    New Member
    New Member
    Posts:5


    --
    19 Oct 2017 04:16 AM
    Thanks, but I don't think I'm being clear. I don't have a problem creating the window or making it appear during the game. The problem is specifically with how the border thickness is rendered. This is my ViewModel...

    public class WindowBase : WindowViewModel
    {
    protected const int _margin = 10;
    protected const int _borderThickness = 5;

    public WindowBase(string templateName)
    : base(templateName)
    {
    Opacity = 1f;
    IsOnTop = true;
    IsHitTestVisible = true;

    // Default border and background colors. Can be overridden on object initialization.
    BorderBrush = new SolidColorBrush(ColorW.White);
    Background = new SolidColorBrush(ColorW.Black);

    // BUG?: Need to set a min width and height in ctor,
    // or borders don't show up when this is rendered in game.
    MinWidth = 10;
    MinHeight = 10;
    }

    // Thickness and border are hard-coded for now
    public Thickness Margin => new Thickness(_margin);
    public Thickness BorderThickness => new Thickness(_borderThickness);

    SolidColorBrush _borderBrush;
    public SolidColorBrush BorderBrush
    {
    get { return _borderBrush; }
    set { SetProperty(ref _borderBrush, value); }
    }

    SolidColorBrush _background;
    public SolidColorBrush Background
    {
    get { return _background; }
    set { SetProperty(ref _background, value); }
    }
    }

    I create it once, and then change the IsVisible state whenever I want to show or hide it. But I also change the position and size of the window every time I show it because I want it to appear next to certain characters, like a speech window. The problem with the border comes in when I change the ratio of the window size to something much different than the 1:1 it's initially set to from the MinWidth and MinHeight I added to the constructor above. If I set the size to something like 200 x 100, then the left and right border thickness with render twice as wide as the top and bottom. I think you calculate the render size for border on first creation of the WindowViewModel, and never again after that even though the window size may change.

    It's not a big deal, just something I thought was odd and that you should know about. I'm working around it now by creating a brand new window every time I want to show it instead of keeping a single one around and changing it's size and position.

    James HaywoodUser is Offline
    New Member
    New Member
    Posts:5


    --
    19 Oct 2017 04:16 AM
    (Duplicate. I don't see a way to delete a post.)
    You are not authorized to post a reply.