wpf: How popup a usercontrol?

2020-06-17 05:46发布

问题:

Background: I have a project which use the datagrid to display the data, and the datagrid has a rowdetail column which include a usercontrol. The usercontrol has some TextBox for user inputing and displaying some message.

Problem: I want to make the usercontrol popup when I click a button, and the popuped usercontrol has the same context as the usercontrol's in the rowdetail column of datagrid. The intention of doing so is to make it easy for users to interactive with the usercontrol because that room of the rowdetail cell is limited.

The usecontrol has be implemente and it can work normally in the rowdetail cell. However, I have no idea about how to pop it up without change its context, such as data source, messages have been display in the TextBox, etc.. Anyone can give me some advices? By the way, I use the MVVM pattern.

EDIT: Here is the RowDetailTemplate:

    <DataTemplate x:Key="RowDetailTemplate">
    <Grid x:Name="RowDetailGrid" HorizontalAlignment="Left" Width="850" Height="355" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        <my:MyUserControl x:Name="myUserControl" />
        <Button Grid.Row="1" Width="60" Height="25" Content="Pop Up" 
                    Command="{Binding Path=PopupCommand}"/>
        .....
    </Grid>
</DataTemplate>

Here is the usercontrol (MyUserControl in the above codes):

<UserControl x:Class="MyProject"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="600">
<Grid>
    <ScrollViewer  Margin="0" HorizontalScrollBarVisibility="Disabled" >
        <StackPanel>
            <ItemsControl Grid.Row="0" ItemsSource="{Binding Output, Mode=OneWay}" FontSize="12">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                            <TextBlock TextWrapping="Wrap" Text="{Binding Path=.}" Foreground="White" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
            <DockPanel Grid.Row="1" LastChildFill="True">                    
                <TextBox Text="{Binding Input, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                     TextWrapping="Wrap"
                     BorderBrush="{x:Null}" SelectionBrush="{x:Null}" 
                     BorderThickness="0" Width="Auto">
                    <TextBox.InputBindings>
                        <KeyBinding Command="{Binding Path=TextBoxEnter}" Key="Enter" />
                    </TextBox.InputBindings>
                </TextBox>
            </DockPanel>
        </StackPanel>
    </ScrollViewer>
</Grid>

回答1:

You can use the Popup control. Attach a Popup to the current row of your datagrid, probably when you click the button is a good place to create the popup and place it as a child of one of cells in the row you are in.
Then you can add the usercontrol to the popup and then 'show' the popup. This way, the DataContext for the popup and thus for the usercontrol is inherited from the containing row in the datagrid.

Below is a very simple implementation of a Popup control just using XAML:

<StackPanel>
  <CheckBox Name="chk1"/>
  <Popup IsOpen="{Binding IsChecked, ElementName=chk1}">
    <Border Background="White">
      <TextBlock Margin="20" Text="I'm Popped Up!"/>
    </Border>
  </Popup>
</StackPanel>

The popup is included in the stackpanel, but is only visible, IsOpen, when the checkbox is checked. You would place your usercontrol in the popup, where I have put the border and textblock. Since the popup is a member of the stackpanel, it automatically uses the DataContext of the stackpanel if it does not have one of its own.

In your instance the stackpanel I am showing would be analogous to your DataGrid row.



回答2:

Well, I would like to just make a comment about Gate Lumas' comment but the system won't let me so I'm putting this down as an answer.

XAML Popup sample: archive of link | original link

If you download that sample and look at the .xaml and .cs files for Senario1, you'll have a perfect example of how to use and implement a popup. Alternatively you can just browse through the code on the site, but I find being able to run and interact with the sample more helpful than just looking at the code.