locked
Changing a Window's ContentTemplate RRS feed

  • Question

  • Hi all,

    I have an application where I frequently need to show simple dialog boxes which have a few buttons and sometimes a text box or a combo box. I didn't want to add a large number of Window subclasses to my project that only differ by the number of buttons or by a single line of XAML, so I tried to create a more generic dialog box that could take an object as Content and a list of objects as button content. That way I can just create them on the spot with one or two lines of code if they just need to show text and buttons, or a bit of XAML if they're more complex than that.

    Stripping away some details, this is what I ended up with:

    <Window x:Class="MyNamespace.GenericDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyNamespace"
        SizeToContent="WidthAndHeight" ResizeMode="NoResize" Title="">
        <Window.ContentTemplate>
            <DataTemplate>
                <Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=local:GenericDialog}}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <ContentControl Content="{Binding Content}" Margin="5"/>
                    <ItemsControl ItemsSource="{Binding Choices}" Grid.Row="1">
                       <!-- buttons here -->
                    </ItemsControl>
                </Grid>
            </DataTemplate>
        </Window.ContentTemplate>
    </Window>
    

    In order to use this to ask the user for a string, I define a little template in my App's resources:

            <ControlTemplate x:Key="AskStringDialog">
                <guitools:GenericDialog Title="Gimme string">
                    <guitools:GenericDialog.Content>
                        <StackPanel>
                            <TextBlock Text="Insert string here:"/>
                            <TextBox/>
                        </StackPanel>
                    </guitools:GenericDialog.Content>
                </guitools:GenericDialog>
            </ControlTemplate>
    

    Then I use LoadContent() on it, and I have my dialog box.

    So, first question: am I doing this in completely the wrong way? What's the best practice for when you need to have dozens of windows that are each slightly different and only marginally more complex than what MessageBox.Show can do?

    Second question: in the example above, I'd like to give a Name to the TextBox so I can easily retrieve the string after calling ShowDialog(). Problem is, I can't. The compiler gives me a MC3093 error if I try to set Name or x:Name to the TextBox. Why?

    Thursday, July 19, 2012 2:33 PM

Answers

All replies

  • Hi Zappo1980,

    -->I have an application where I frequently need to show simple dialog boxes which have a few buttons and sometimes a text box or a combo box

    I think you could not create a basic window with custom template to achieve this goal, because the template is the appearence of our window, you could not fix your content(sometimes textBox, sometimes ComboBox), so you re-template the window will not fit for your needs, I suggest you host your content(TextBox, ComboBox, or other ItemsControls) into a Grid, or layout them into another panel, and then you just set the Content property of your window, likes:

    Window.Content = ....;

    If you want to pass data, you could set DataContext proprety.

    best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, July 20, 2012 6:02 AM
  • Hello Sheldon _Xiao,

    Thanks for your suggestion. The point is that *some* of the appearance is indeed shared between all windows; for example, the way the buttons are laid out. If I did what you suggested, I would effectively be sharing nothing at all.

    Also, I figure that I could fix this by not changing the Window's ContentTemplate, and instead using a new DependencyProperty instead of using Window.Content. It's just that, well, I thought that this sort of stuff is exactly what modifying the ContentTemplate is about: having a Window that presents its Content in a specific fashion. In this case, by having a row of buttons below it. Why would this prevent me from naming elements in the Content?

    Friday, July 20, 2012 8:00 AM
  • Hi Zappo1980,

    Change the controltemplate property of window is not good method to achieve your goal. As for second question, I think you could refer to this connect:

    https://connect.microsoft.com/VisualStudio/feedback/details/483024/wpf-error-message-cannot-set-name-attribute-value-0-on-element-1-1-is-under-the-scope-of-element-2-which-already-had-a-name-registered-when-it-was-defined-in-another-scope

    If you need further explaination, please let me know, I will discuss it with you.

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Sheldon _Xiao Tuesday, August 7, 2012 6:33 AM
    Tuesday, July 24, 2012 1:15 AM
  • Hi Zappo1980,
     
    I am marking your issue as "Answered", if you have new findings about your issue, please let me know.


    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, August 7, 2012 6:34 AM