Window size and TabControl with DataBinding (Size of Items) - wpf

The following scenario bothers me:
I have a simple WPF Window that has a TabControl as content. The ItemsSource of the TabControl is bound to a list of objects. In order to visualize the objects I defined some DataTemplates. As the list of objects may have different types, the right visualization is chosen by the default template selector. This works fine and does not cause any trouble.
The issue that came up is the size of the window. The DataTemplates have different sizes. And I want the dialog to have a size that the largest DataTemplate fits. When I use SizeToContent in the Window, the Window changes its size everytime I change the tabs.
So, my questions is, how can I achieve to make the window fit the largest TabItem (which size is determined by the DataTemplate)?
thanks,
Florian

The problem you are having, is that because the larger DataTemplate is not shown, it's size is not taken into account when sizing to content.
Your options:
1) Manually set (min)width/height on appropriate controls (tabcontrol, Window, DataTemplate, etc)
2) If you know that a certain tab is always going to be bigger than the rest, you can bind the width/height of the other tabs to the bigger tab:
<TabItem>
<StackPanel Name="stackPanelBiggest" />
</TabItem>
<TabItem>
<StackPanel Width="{Binding ElementName=stackPanelBiggest, Path=ActualWidth}" />
</TabItem>
I think that for the above to work, the biggest tab has to be first one shown. Although the tab control destroys the visual tree of the previous tab when swithching to another tab, this method is still working for me (despite the fact that the ActualWidth should be 0 or NaN, after switching tabs).

Related

TextTrimming in panel in ScrollViewer

I am trying to set up an element within a WPF application, but cannot get the TextTrimming on the TextBlocks to work properly. This is within a ScrollViewer. I am currently using a DockPanel as the inner container.
I have searched quite a bit, but found no questions addressing this issue.
The XAML for the container:
<Grid>
<ScrollViewer>
<DockPanel Name="listedCharacters" LastChildFill="False"></DockPanel>
</ScrollViewer>
</Grid>
The XAML for the child elements (added by code):
<UserControl …>
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding FullName}" TextTrimming="CharacterEllipsis" />
</Grid>
</UserControl>
The first problem is that whether I use the DockPanel or a StackPanel, as the inner container, the child element's width appears to be dictated by its content (the TextBlocks) rather than constrained by the parent ScrollViewer.
The effect I want is for the ellipsis to truncate each TextBlock's content when the Window's grid column (not shown in code) is narrower than the bound text. Basically, a list that scrolls vertically when needed, and trims horizontally (which I thought would have been sufficiently common that the answer would be out there; alas, no).
I believe I need to use my own UserControl for this, as there is a lot more going on than shown her; right-click menus on the item in the list, etc.
The secondary issue, iff the optimal panel to use is the DockPanel, how to apply the DockPanel.Dock="Top" through code (C#) when the elements are dynamically added? Again, I cannot find anything that appears to explain this. (I know it is probably in the wrong place in the sample code above.)

WPF automatic resize font until it fits within parent control

I have a user control who's root element is a Grid.
I also have have a ContentControl that serves as a placeholder for some text that is filled when data is loaded. This control can be moved around within the user control and so it's position can be anywhere.
If the text is too long to fit within the root Grid of the user control, I want to reduce the font size of the ContentControl until the text fits.
My problem is that I can't seem to find an event that I can handle to do this process.
I tried using the ContentControl.LayoutUpdated event;however, the sender parameter for this always appears to be nothing...which is really not helpful!
I am really looking forward to any advise on how to achieve this.
Thank you
-Frinny
Wrapping your ContentControl in a Viewbox set to only scale down will do this for you:
<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
<ContentControl Content="Some Text"/>
</Viewbox>

Silverlight Animating Control in ListBox

I've got a user control that I'm using as my DataTemplate for all the items in my ListBox. There's an animation in said UserControl that's pretty simple - it just expands a certain ListBox, and it works. The thing is, when I scroll, every Nth item ALSO has the ListBox expanded, where N depends on how big my browser is sized to (in other words, how many items the ListBox is holding at any one time.)
It seems as though new items getting loaded into the listbox as I scroll are tripping over this animation. Is there anything I can do about this?
If your outer ListBox contains only a few items then add this to its Xaml:-
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItesmPanelTemplate>
</ListBox.ItemsPanel>
By default the ListBox uses a VirtualizingStackPanel which only contains concrete instances of ListBoxItem that are currently being displayed. Items a generated as needed by a ItemContainerGenerator which will recycle existing items. I suspect some in there the state of an ListBoxItem is not entirely cleared when re-used to display another item from the ItemsSource.

Linear navigation in WPF MVVM

I'm using the Cinch MVVM framework, however I think this is something that relates to all WPF approaches.
I want to have a primary screen - Shell or MainWindow - which then contains various viewmodels. To navigate between viewmodels I'm using (or going to use) a tab control styled as a button strip with the content area beneath - which is all ok as I add the viewmodels to the tabcontrol (well to the 'Views' collection which is bound to the tab control) at runtime.
A screen that doesn't fit into this methodology is the sign in screen, which I don't really want to add to the tab control - preferably it should be in it's own usercontrol which takes up the entire screen apart from covering the logo; that is, I would like it to appear in the same window rather than a popup dialog, however I'm not sure how to add/ remove controls dynamically and then add subsequent tabcontrol once the user has signed in successfully (and remove the sign in screen). What containers should be used?
TIA.
The easiest way is put your tabcontrol in a Grid without columns and rows so it fill the grid by default. Then add an extra grid or loginusercontrol to the grid as shown below. The moment a user needs to login you can set the visibility of the MainTabControl" to collapsed and of the LoginGrid to Visible and switch it back after a succesfull login. I hope that the xaml below will help you enough.
<Grid>
<TabControl x:Name="MainTabControl" Visiblity="Visible">
... put your tabs here ...
</TabControl>
<Grid x:Name="LoginGrid" Background="#60FFFFFF" Visibility="Collapsed">
... put your usercontrol to login here or the login controls themself
</Grid>
</Grid>
You could use a ContentControl with content bound to a view model. So you'd have two view-models representing the sign-in screen and the main screen and use DataTemplate to display appropriate screen.
<Window.Resources>
...
<DataTemplate DataType="{x:Type my_view_models:SignInViewModel}">
<my_controls:SignInScreenView />
</DataTemplate>
...
</Window.Resources>
<ContentControl Content={Binding} />
You may be interested by Lakana, it is a lightweight and non intrusive navigation framework for WPF.
Riana

ListBox with ItemTemplate (and ScrollBar!)

I have a databound and itemtemplated ListBox:
<ListBox x:Name="lbLista"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Deleteable, Mode=TwoWay}" />
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The ites show fine and they come from an ObservableCollection.
The problem is the scrollbar which appears but is not usable - it does not have a handle to grab. I've tried setting some ScrollView attached properties on ListBox, but they do not affect the situation.
I pasted your code into test project, added about 20 items and I get usable scroll bars, no problem, and they work as expected. When I only add a couple items (such that scrolling is unnecessary) I get no usable scrollbar. Could this be the case? that you are not adding enough items?
If you remove the ScrollViewer.VerticalScrollBarVisibility="Visible" then the scroll bars only appear when you have need of them.
ListBox will try to expand in height that is available.. When you set the Height property of ListBox you get a scrollviewer that actually works...
If you wish your ListBox to accodate the height available, you might want to try to regulate the Height from your parent controls.. In a Grid for example, setting the Height to Auto in your RowDefinition might do the trick...
HTH
I have never had any luck with any scrollable content placed inside a stackpanel (anything derived from ScrollableContainer. The stackpanel has an odd layout mechanism that confuses child controls when the measure operation is completed and I found the vertical size ends up infinite, therefore not constrained - so it goes beyond the boundaries of the container and ends up clipped. The scrollbar doesn't show because the control thinks it has all the space in the world when it doesn't.
You should always place scrollable content inside a container that can resolve to a known height during its layout operation at runtime so that the scrollbars size appropriately. The parent container up in the visual tree must be able to resolve to an actual height, and this happens in the grid if you set the height of the RowDefinition o to auto or fixed.
This also happens in Silverlight.
-em-
Thnaks for answer. I tried it myself too to an Empty Project and - lo behold allmighty creator of heaven and seven seas - it worked. I originally had ListBox inside which was inside of root . For some reason ListBox doesn't like being inside of StackPanel, at all! =)
-pom-

Resources