ArthurT
ArthurT

Reputation: 367

UI Elements disappearing from WPF at runtime

I am developing a WPF application that allows to connect two peers in a video chat. I have been designed the UI in the XAML designer for the last two months and everything went fine, when I ran the application it did show everything etc. Until yesterday, for absolutely no apparent reason. Some part of the UI just does not show up anymore WHEN the code is running on another laptop. I insist on the fact that it did work before and now not anymore. I also did not change anything in the code that could have anything to do with that part of the UI, nor in the xaml.

I did check that I never mess up with any Visibility parameter in the code-behind as well, so I don't see any reason why the behavior of the application suddenly changed.

Does anyone have an idea why this would happen?

Here is the xaml:

<Window x:Class="RealSenseiConfFusion.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="1000" Width="1500"
    WindowStartupLocation="Manual"
    Left="0" Top="0"
    Closing="Window_Closing"
    Loaded="Window_Loaded" >
<Grid Background="LightSteelBlue">
    <Rectangle Margin="10,10,498.6,0" Name="rectangle1" Stroke="Black" RadiusX="9" RadiusY="9" Fill="LightSlateGray" Height="142" VerticalAlignment="Top" />
    <Grid Name="callAndSyncGrid" Margin="26,24,1165,835" Background="LightGray">
        <StackPanel>
            <TextBlock HorizontalAlignment="Center">ABOUT CALL</TextBlock>
            <TextBlock Name="myIpTextBlock">Your ip is:</TextBlock>
            <Grid Name="callGrid">
                <TextBox Height="23" HorizontalAlignment="Left" Name="txtIP" Background="GhostWhite" Foreground="Black" Width="221" />
                <Button Height="23" HorizontalAlignment="Right" Name="btnCall" Width="75" Click="btnCall_Click">Call</Button>
            </Grid>
            <Button Name="btnSync" Content="Start Synchronization" HorizontalAlignment="Left" Width="120" Height="25" Click="btnSynchronize_Click"/>
            <TextBlock Name="currentConvText"></TextBlock>
        </StackPanel>
    </Grid>
    <Grid Name="visSetupGrid" Margin="650,24,515,835" Background="LightGray">
        <StackPanel>
            <TextBlock HorizontalAlignment="Center">VISUALIZATION SETUP</TextBlock>
            <Grid>
                <TextBlock HorizontalAlignment="Left">  Visualization block 1:</TextBlock>
                <ComboBox Name="vis1Combo" HorizontalAlignment="Right">
                    <ComboBoxItem IsSelected="True">Vis1UC1</ComboBoxItem>
                    <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                    <ComboBoxItem>Vis1UC2</ComboBoxItem>
                    <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC1</ComboBoxItem>
                    <ComboBoxItem>Vis2UC2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC3</ComboBoxItem>
                    <ComboBoxItem>Vis3UC1</ComboBoxItem>
                    <ComboBoxItem>Vis3UC2</ComboBoxItem>
                    <ComboBoxItem>Vis3UC3</ComboBoxItem>
                </ComboBox>
            </Grid>
            <Grid>
                <TextBlock HorizontalAlignment="Left">  Visualization block 2:</TextBlock>
                <ComboBox Name="vis2Combo" HorizontalAlignment="Right">
                    <ComboBoxItem>Vis1UC1</ComboBoxItem>
                    <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                    <ComboBoxItem>Vis1UC2</ComboBoxItem>
                    <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC1</ComboBoxItem>
                    <ComboBoxItem IsSelected="True">Vis2UC2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC3</ComboBoxItem>
                    <ComboBoxItem>Vis3UC1</ComboBoxItem>
                    <ComboBoxItem>Vis3UC2</ComboBoxItem>
                    <ComboBoxItem>Vis3UC3</ComboBoxItem>
                </ComboBox>
            </Grid>
            <Grid>
                <TextBlock HorizontalAlignment="Left">  Visualization block 3:</TextBlock>
                <ComboBox Name="vis3Combo" HorizontalAlignment="Right">
                    <ComboBoxItem>Vis1UC1</ComboBoxItem>
                    <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                    <ComboBoxItem IsSelected="True">Vis1UC2</ComboBoxItem>
                    <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC1</ComboBoxItem>
                    <ComboBoxItem>Vis2UC2</ComboBoxItem>
                    <ComboBoxItem>Vis2UC3</ComboBoxItem>
                    <ComboBoxItem>Vis3UC1</ComboBoxItem>
                    <ComboBoxItem>Vis3UC2</ComboBoxItem>
                    <ComboBoxItem>Vis3UC3</ComboBoxItem>
                </ComboBox>
            </Grid>
            <Button Name="btnVisApply" HorizontalAlignment="Center" Click="btnVisApply_Click">Apply!</Button>
        </StackPanel>
    </Grid>
    <Grid Name="otherPeerVideo" HorizontalAlignment="Left" VerticalAlignment="Top" Width="1000" Height="700" Margin="0,83,0,0">
        <Grid Width="960" Height="540">
            <Border BorderBrush="DarkOrange" BorderThickness="4">
                <WindowsFormsHost Name="wfServer"/>
            </Border>
        </Grid>
    </Grid>
    <StackPanel Name="feedbackAndMyVideoStackPanel" Background="WhiteSmoke" Margin="1000,83,0,0" VerticalAlignment="Top" Width="454" Height="800">
        <Grid Name="vis1Grid" Height="160"></Grid>
        <Grid Name="vis2Grid" Height="160"></Grid>
        <Grid Name="vis3Grid" Height="160"></Grid>
        <Grid Name="myVideoGrid" VerticalAlignment="Bottom" Height="320">
            <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="454" Height="300">
                <Border BorderBrush="Blue" BorderThickness="4">
                    <WindowsFormsHost Name="myVideo" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="446" Height="292"/>
                </Border>
            </Grid>
            <Button Name="myVideoHideButton" Click="myVideoHideButton_Click" HorizontalAlignment="Right" VerticalAlignment="Top" Width="80" Height="20">Hide/Unhide</Button>
        </Grid>
    </StackPanel>
</Grid>

Here is a screenshot of how it looks like in the designer (on both machines): Designer look

Here is a screenshot of how it looks like when the application is running on my machine: enter image description here

And here a screenshot of how it looks like when the application is running on the laptop: enter image description here

Upvotes: 1

Views: 2527

Answers (2)

Emmanuel DURIN
Emmanuel DURIN

Reputation: 4913

I compiled/tried your code. When the window gets small, many components disappear. Because of the margins.

Example of margins replacement

  • Before :

With margins for placement

<Grid Name="callAndSyncGrid" Margin="26,24,1165,835" Background="LightGray">
    <!-- ... -->
</Grid>
<Grid Name="visSetupGrid" Margin="650,24,515,835" Background="LightGray">
        <!-- ... -->
</Grid>
  • After

With margins for "breathing"
Placement is made with two columns (ColumnDefinitions and Grid.Column="1"; 0 by default).
Here each Column takes 50 % (50*) of the available room.
You can also express the size as "Auto" or 323 (hardcoded size)

<Grid Name="parentGridForLayout" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50*"/> 
        <ColumnDefinition Width="50*"/> 
    </Grid.ColumnDefinitions>   
    <Grid Name="callAndSyncGrid" Margin="10" Background="LightGray">
        <!-- ... -->
    </Grid>
    <Grid Name="visSetupGrid" Margin="10"  Background="LightGray">
            <!-- ... -->
    </Grid>
</Grid>

Advice

Using Grid+margin or Canvas are pretty close approaches. But with Grid you can create Columns and Rows to organize layout. And you can compose Grids(or other Panels like StackPanels, DockPanels, WrapPanels) into Grids for organizing the layout.

Disclaimer : My piece of code alone is not enough.
You need to organize all your GUI, with many panels.
I would recreate the window from scratch : empty page, then put a first Grid (or any suitable Panel), split it with columns or rows. Then put some content imported from previous window at the grid level then go in the children grid to put some more grids/imported content

Regards

Upvotes: 1

ArthurT
ArthurT

Reputation: 367

As @HighCore and @Emmanuel DURIN pointed out, the problem was that I defined the layout with Margins, which can lead to big trouble if I run the application on different screen sizes. To correct this, I used Canvas'es in order to place every element with respect to their containers. Now I can use the application on different screens and everything gets displayed as I want it.

Here the better layouted UI for reference:

<Window x:Class="RealSenseiConfFusion.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="860" Width="1500"
    WindowStartupLocation="Manual"
    Left="0" Top="0"
    Closing="Window_Closing"
    Loaded="Window_Loaded" >
<Grid Background="LightSteelBlue">
    <Canvas>
        <Canvas Canvas.Top="10" Canvas.Left="10" Width="980" Height="142">
            <Rectangle Width="980" Height="132" Name="rectangle1" Stroke="Black" RadiusX="9" RadiusY="9" Fill="LightSlateGray" VerticalAlignment="Top" />
            <Grid Name="callAndSyncGrid" Canvas.Top="15" Canvas.Left="15" Width="200" Background="LightGray">
                <StackPanel>
                    <TextBlock HorizontalAlignment="Center">ABOUT CALL</TextBlock>
                    <TextBlock Name="myIpTextBlock">Your ip is:</TextBlock>
                    <Grid Name="callGrid">
                        <TextBox Height="23" HorizontalAlignment="Left" Name="txtIP" Background="GhostWhite" Foreground="Black" Width="221" />
                        <Button Height="23" HorizontalAlignment="Right" Name="btnCall" Width="75" Click="btnCall_Click">Call</Button>
                    </Grid>
                    <Button Name="btnSync" Content="Start Synchronization" HorizontalAlignment="Left" Width="120" Height="25" Click="btnSynchronize_Click"/>
                    <TextBlock Name="currentConvText"></TextBlock>
                </StackPanel>
            </Grid>
            <Grid Name="visSetupGrid" Canvas.Top="15" Canvas.Right="15" Width="200" Background="LightGray">
                <StackPanel>
                    <TextBlock HorizontalAlignment="Center">VISUALIZATION SETUP</TextBlock>
                    <Grid>
                        <TextBlock HorizontalAlignment="Left">  Visualization block 1:</TextBlock>
                        <ComboBox Name="vis1Combo" HorizontalAlignment="Right">
                            <ComboBoxItem IsSelected="True">Vis1UC1</ComboBoxItem>
                            <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                            <ComboBoxItem>Vis1UC2</ComboBoxItem>
                            <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC1</ComboBoxItem>
                            <ComboBoxItem>Vis2UC2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC3</ComboBoxItem>
                            <ComboBoxItem>Vis3UC1</ComboBoxItem>
                            <ComboBoxItem>Vis3UC2</ComboBoxItem>
                            <ComboBoxItem>Vis3UC3</ComboBoxItem>
                        </ComboBox>
                    </Grid>
                    <Grid>
                        <TextBlock HorizontalAlignment="Left">  Visualization block 2:</TextBlock>
                        <ComboBox Name="vis2Combo" HorizontalAlignment="Right">
                            <ComboBoxItem>Vis1UC1</ComboBoxItem>
                            <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                            <ComboBoxItem>Vis1UC2</ComboBoxItem>
                            <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC1</ComboBoxItem>
                            <ComboBoxItem IsSelected="True">Vis2UC2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC3</ComboBoxItem>
                            <ComboBoxItem>Vis3UC1</ComboBoxItem>
                            <ComboBoxItem>Vis3UC2</ComboBoxItem>
                            <ComboBoxItem>Vis3UC3</ComboBoxItem>
                        </ComboBox>
                    </Grid>
                    <Grid>
                        <TextBlock HorizontalAlignment="Left">  Visualization block 3:</TextBlock>
                        <ComboBox Name="vis3Combo" HorizontalAlignment="Right">
                            <ComboBoxItem>Vis1UC1</ComboBoxItem>
                            <ComboBoxItem>Vis1UC1_2</ComboBoxItem>
                            <ComboBoxItem IsSelected="True">Vis1UC2</ComboBoxItem>
                            <ComboBoxItem>Vis1UC2_2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC1</ComboBoxItem>
                            <ComboBoxItem>Vis2UC2</ComboBoxItem>
                            <ComboBoxItem>Vis2UC3</ComboBoxItem>
                            <ComboBoxItem>Vis3UC1</ComboBoxItem>
                            <ComboBoxItem>Vis3UC2</ComboBoxItem>
                            <ComboBoxItem>Vis3UC3</ComboBoxItem>
                        </ComboBox>
                    </Grid>
                    <Button Name="btnVisApply" HorizontalAlignment="Center" Click="btnVisApply_Click">Apply!</Button>
                </StackPanel>
            </Grid>
        </Canvas>

        <Grid Name="otherPeerVideo" HorizontalAlignment="Left" Canvas.Top="150" Canvas.Left="20">
            <Grid Width="960" Height="540">
                <Border BorderBrush="DarkOrange" BorderThickness="4">
                    <WindowsFormsHost Name="wfServer"/>
                </Border>
            </Grid>
        </Grid>

        <StackPanel Name="feedbackAndMyVideoStackPanel" Background="WhiteSmoke" Canvas.Right="15" Canvas.Top="15" VerticalAlignment="Top" Width="454" Height="800">
            <Grid Name="vis1Grid" Height="160"></Grid>
            <Grid Name="vis2Grid" Height="160"></Grid>
            <Grid Name="vis3Grid" Height="160"></Grid>
            <Grid Name="myVideoGrid" VerticalAlignment="Bottom" Height="320">
                <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="454" Height="300">
                    <Border BorderBrush="Blue" BorderThickness="4">
                        <WindowsFormsHost Name="myVideo" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="446" Height="292"/>
                    </Border>
                </Grid>
                <Button Name="myVideoHideButton" Click="myVideoHideButton_Click" HorizontalAlignment="Right" VerticalAlignment="Top" Width="80" Height="20">Hide/Unhide</Button>
            </Grid>
        </StackPanel>
    </Canvas>
</Grid>

Upvotes: 0

Related Questions