0

I have a project created in C# in Visual Studio 2013 Express, a WPF application. when run with the debugger from Visual Studio, the application Window appears the correct size, but when running the same generated executable from the bin folder, the window is about 5-7px taller. It's worth mentioning that the Window.Height is controlled dynamically by the underlying code.

That said, why does the size differ during runtime like it does? I'm new to development on Windows.

Here's my code that does the resizing:

const int WindowBaseHeight = 94;
const int ItemHeight = 68;
ObservableCollection<obj> CurrentItems = new ObservableCollection<obj>();

AppWindow.Height = WindowBaseHeight + ItemHeight * CurrentItems.Count;
parashep
  • 115
  • 7
  • Could you show your code that performs the resizing of the window? – Adam Zuckerman Mar 09 '14 at 21:46
  • @Adam there you go, relevant portions added. – parashep Mar 09 '14 at 21:49
  • It would seem that you are changing your height based on the number of items you have in your collection. Is it possible that you have more in the collection than you are expecting? – Adam Zuckerman Mar 09 '14 at 21:51
  • @Adam nope, I don't think so. the height difference would be much more, plus there's also the fact that it works perfectly when run inside Visual Studio. when running it outside of Visual Studio, the difference is less than 10 pixels for sure. – parashep Mar 09 '14 at 21:53
  • What happens if you add and remove items from your collection? Does you window resize appropriately and the correct size? – Adam Zuckerman Mar 09 '14 at 21:56
  • @Adam mhm, everything is exactly as it should be in the debugger. when the collection is generated, the window is resized and it is seamless. I'm not sure if it's a code issue or an issue with me not knowing something about how height is calculated outside of Visual Studio... – parashep Mar 09 '14 at 21:59
  • I don't know what mhm means. Also, you don't have to address the comment directly to me as I get a notification without it. There are a lot of things that can affect the height of a Windows application. Based on what you have included, it shouldn't be happening. Could there be code in a resize event? – Adam Zuckerman Mar 09 '14 at 22:04
  • sorry, by mhm I meant yes. the only other code in the same method that sets the height is code that pulls XML data from the internet and creates the collection out of it. at the very end, it sets the height. – parashep Mar 09 '14 at 22:07
  • 1
    your code doesn't make sense. What if `CurrentItems.Count` is 2.5 billion? are you going to have a Window `2.5b * itemheight` tall? – Federico Berasategui Mar 09 '14 at 22:47
  • I suppose. but there should be no more than 3 or 4 items maximum in the collection, ever. it's not user-determined. – parashep Mar 09 '14 at 23:11

1 Answers1

1

Ok. Take a deep breath, then delete your code and start all over.

First of all, if you're working with WPF, you need to leave behind any and all approaches you might be used to from other technologies and understand and embrace The WPF Mentality.

Basically, you never need to do any manipulations of layout, nor manual resizing of UI elements, nor anything like that in procedural code, because WPF is Resolution Independent by default and it provides several mechanisms to create auto-adjustable layouts and UIs that fit perfectly regardless of the available screen/window size.

In order to make the Window auto-size itself to it's contents' size, you must set the Window.SizeToContent property accordingly.

Another very important aspect that you need to understand is that in WPF, any UI that shows "items" (any UI that shows 2 or more of the same "thing", regardless what the "thing" is) should be implemented using an ItemsControl.

This is how you create an auto-adjustable items-based UI in WPF where the items have a height of 68:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="Height" Width="200">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Height="68" Background="LightCyan">
                    <TextBlock Text="{Binding}" 
                               VerticalAlignment="Center" 
                               HorizontalAlignment="Center"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

Code behind (for the sake of the example):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = Enumerable.Range(0, 4).Select(x => "Item" + x.ToString());
    }
}

Result:

enter image description here

  • Notice how I'm using the ItemsControl and DataBinding it's ItemsSource property in order to declaratively define the UI in proper XAML instead of procedurally creating the UI in code. This is the preferred approach in WPF for everything.

  • This approach reduces code behind to practically zero. As you can see in my example, all I'm doing is setting the DataContext of the Window to a relevant piece of data that can be used for DataBinding.

  • Also notice that there is no code whatsoever doing any manipulations of the UI. The Window size is set by WPF according to the value of the SizeToContent property, which is set to Height.

  • I'm binding to a List<string>, for the sake of the example, but you can databind to any types of .Net objects in WPF, and even directly to XML.

  • WPF Rocks. - Simply copy and paste my code in a File -> New Project -> WPF Application and see the results for yourself.

  • I suggest you read the linked material in this post, most importantly the "WPF Mentality" post, the DataBinding Overview, and the ItemsControl series. Let me know if you need further help.

Community
  • 1
  • 1
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
  • oh! thank you for this good answer. I'm already using an `ItemsControl` so I think this `Window.SizeToContent` property that I didn't know about is definitely what I should be using. I'm still getting used to WPF, but I'm sure this will help me do things the right way. – parashep Mar 09 '14 at 23:46
  • yes! sure enough, that fixed my problem with the inconsistencies. thanks a lot. – parashep Mar 09 '14 at 23:54