I am creating a Silverlight dialog class which is more MVVM-friendly. The ChildWindow
class has some awkwardness which makes it difficult to manage from a view model.
This means I need to declare my own user interface. I have all of the traditional elements in place, including a Popup
control and an overlay with 50% opacity. The open/close behavior is also working.
The problem I am having is that my control template doesn't prevent the dialog body from growing in response to the user typing into a TextBox
. When the amount of characters grows beyond the default size,开发者_运维百科 the entire dialog body stretches horizontally. Obviously this is not normal behavior.
What I would like to accomplish is a way for the dialog body to size itself appropriately to the content, but not expand or contract in response to child controls which require more or less space. This is how the ChildWindow
control behaves, but I have examined its template and I can't determine how that works.
I think I am seeing the expansion behavior because my template is based on Grid
s, which allow child controls as much size as they request. I have tried several permutations of StackPanel
, ScrollViewer
, and other layouts with no success. Does anyone have some insight into how ChildWindow
accomplishes its static, content-sized layout, or perhaps another suggestion?
Here is the template I have so far, stripped down to the bare essentials:
<Popup>
<Grid x:Name="overlay">
<Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...Title...
</Grid>
<Grid Grid.Row="1">
<ContentControl Content="{TemplateBinding DialogBody}" />
</Grid>
</Grid>
</Border>
</Grid>
</Popup>
When DialogBody
contains a TextBox
or anything else which changes the layout size, such as hidden controls, the entire content of the Popup
grows. I don't want to resort to a static width and height, because I want the dialog to automatically size to the dialog body, but only initially.
Not sure that this is wat you want..., but wyh don't you register for Loaded event of "overlay" nad when Load will fire set the heigh and width of "overlay" ActualHeight and ActualWidth accordingly. In this way control will get the size it want initially and wont change after that.
EDIT: you can use this to do this in declarative way.
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard x:Name ="setWidth">
<DoubleAnimation Storyboard.TargetName="overlay" Storyboard.TargetProperty="Width" From="0" To="{Binding ActualWidth, ElementName=overlay}"/>
<DoubleAnimation Storyboard.TargetName="overlay" Storyboard.TargetProperty="Height" From="0" To="{Binding ActualHeight, ElementName=overlay}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
精彩评论