C# 在Win8 Metro应用程序中动态创建可拖动的用户控件

C# 在Win8 Metro应用程序中动态创建可拖动的用户控件,c#,xaml,windows-runtime,microsoft-metro,datatemplate,C#,Xaml,Windows Runtime,Microsoft Metro,Datatemplate,现在我有一个视图,它用绑定到用户列表的平铺填充ListView。单击这些平铺(按钮)中的任何一个,我都需要动态创建一个小的可拖动窗口,该窗口由包含ScrollViewer&ItemsControl、Textbox和按钮的StackPanel组成。然后,必须根据单击用户磁贴的位置将其绑定到ObservableCollection 这将用于私人聊天场景 我已经实现了一个绑定到ObservableCollection的群组聊天,但这是在页面导航中创建的 我已经开始将同一组控件添加到Resources.

现在我有一个视图,它用绑定到用户列表的平铺填充ListView。单击这些平铺(按钮)中的任何一个,我都需要动态创建一个小的可拖动窗口,该窗口由包含ScrollViewer&ItemsControl、Textbox和按钮的StackPanel组成。然后,必须根据单击用户磁贴的位置将其绑定到ObservableCollection

这将用于私人聊天场景

我已经实现了一个绑定到ObservableCollection的群组聊天,但这是在页面导航中创建的

我已经开始将同一组控件添加到Resources.xaml的dataTemplate中,但是对于下一步要去哪里,我完全不知道

<DataTemplate x:Key="PrivateChatTemplate">
    <StackPanel Width="267" Height="300" >
        <ScrollViewer x:Name="PrivateScrollViewer" Grid.ColumnSpan="2" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" >
            <ItemsControl Name="PrivateItemsControl" Foreground="Black" />
        </ScrollViewer>
        <TextBox x:Name="PrivateTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="201" Height="60" BorderThickness="1" BorderBrush="Black"/>
        <Button x:Name="PrivateSendButton" Content="Send" HorizontalAlignment="Left" Height="58" Margin="65,2,0,0" VerticalAlignment="Top" Width="66"   Click="PrivateSendButton_Click" Background="Black"/>
    </StackPanel>       
</DataTemplate>


谢谢你的帮助。

有趣的是,你提到了一个
ScrollViewer
,因为这让我想到了使用
ScrollViewer
在其他内容前面放置一个前景窗口控件,而且它相当简单

在页面内部-放置一个扩展到应用程序窗口全部大小的
滚动查看器
(通过将
垂直对齐
水平对齐
设置为
拉伸
),它有一个
面板
,像
画布
网格
,并将窗口/
用户控件
放在里面-像下面代码中的
矩形
。通过将
-ScrollMode/-ScrollBarVisibility
值和面板大小设置为大于
ScrollViewer的
视口宽度
视口高度
,确保
ScrollViewer可以双向滚动。您应该处理
ScrollViewer
及其内部窗口上的
SizeChanged
事件,并将面板的
宽度和
高度设置为

panel.Width = scrollViewer.ViewportWidth * 2 - window.ActualWidth;
panel.Height = scrollViewer.ViewportHeight * 2 - window.ActualWidth;
现在一切都可以通过触摸滚动了。剩下的问题是处理鼠标输入,您可以根据窗口上的
指针-
事件来处理鼠标输入

XAML

<Page
    x:Class="DraggableWindow.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DraggableWindow"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="99"
            Margin="112,101,0,0"
            VerticalAlignment="Top"
            Width="119" />
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="147"
            Margin="985,389,0,0"
            VerticalAlignment="Top"
            Width="262" />
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="147"
            Margin="403,581,0,0"
            VerticalAlignment="Top"
            Width="262" />
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="147"
            Margin="112,277,0,0"
            VerticalAlignment="Top"
            Width="262" />
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="147"
            Margin="682,129,0,0"
            VerticalAlignment="Top"
            Width="262" />
        <Button
            Content="Button"
            HorizontalAlignment="Left"
            Height="147"
            Margin="551,371,0,0"
            VerticalAlignment="Top"
            Width="262" />
        <ScrollViewer
            x:Name="scrollViewer"
            SizeChanged="OnScrollViewerSizeChanged"
            Background="{x:Null}"
            HorizontalAlignment="Stretch"
            VerticalAlignment="Stretch"
            HorizontalScrollMode="Auto"
            HorizontalScrollBarVisibility="Hidden"
            VerticalScrollBarVisibility="Hidden"
            IsHorizontalRailEnabled="False"
            IsVerticalRailEnabled="False">
            <Canvas
                x:Name="panel">
                <Rectangle
                    x:Name="window"
                    SizeChanged="OnWindowSizeChanged"
                    PointerPressed="OnWindowPointerPressed"
                    PointerMoved="OnWindowPointerMoved"
                    PointerReleased="OnWindowPointerReleased"
                    Fill="LightGray"
                    Width="200"
                    Height="150"/>
            </Canvas>
        </ScrollViewer>
    </Grid>
</Page>

哦,为了使它成为动态的-将它包装在一个
UserControl
中处理那里的事件,并将其放入一个
弹出窗口
。当我有机会的时候,我会考虑将所有这些包装在一个可重用控件中,因为我的可视化树调试器覆盖也需要类似的东西。

@Filip Skakun不幸的是,我必须使用8.0而不是8.1,所以没有新的ChangeView方法。我试图创建一个自定义用户控件,但我不确定如何处理SizeChanged和UpdateWindowingLayout,因为窗口将在单击按钮时创建,基本上是动态创建的。然后,我需要将字符串列表绑定到UserControl中的ItemsControl。
`不幸的是,我不得不使用8.0而不是8.1,因此没有新的ChangeView方法。我试图创建一个自定义用户控件,但我不确定如何处理SizeChanged和UpdateWingLayout(实现拖动),因为窗口将在单击按钮时创建,基本上是动态创建的。然后我需要将字符串列表绑定到UserControl中的ItemsControl

    <UserControl
x:Class="KeyOui.View.PrivateChatWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:KeyOui.View"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="300">

<StackPanel Background="Indigo">
    <ScrollViewer>
        <ItemsControl Name="PrivateChatItemsControl" ItemsSource="{Binding ListOfMessages.Name}" Width="Auto" Height="150" Foreground="Black" BorderBrush="Gray" BorderThickness="2" />
    </ScrollViewer>
    <StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" HorizontalAlignment="Stretch">
        <TextBox x:Name="GroupChatTextBox" VerticalAlignment="Bottom" TextWrapping="Wrap" FontSize="14" Width="140" Height="40" Margin="5,5,5,5" BorderThickness="1" BorderBrush="Gray"/>
        <Button x:Name="SendButton" Content="Send"  
                        HorizontalAlignment="Left" Height="40" 
                        VerticalAlignment="Top" Width="Auto"  
                        Click="SendButton_Click"  Margin="5,5,5,5"
                        BorderThickness="1" BorderBrush="Gray"/>
    </StackPanel>
</StackPanel>


我现在看到的-
ScrollViewer
在这里似乎没有多大帮助,因为您无论如何都需要自己处理输入。一个更好的解决方案可能是迪德里克在他的书中描述的。不过我刚开始做我自己的窗口控制。
    <UserControl
x:Class="KeyOui.View.PrivateChatWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:KeyOui.View"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200"
d:DesignWidth="300">

<StackPanel Background="Indigo">
    <ScrollViewer>
        <ItemsControl Name="PrivateChatItemsControl" ItemsSource="{Binding ListOfMessages.Name}" Width="Auto" Height="150" Foreground="Black" BorderBrush="Gray" BorderThickness="2" />
    </ScrollViewer>
    <StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" HorizontalAlignment="Stretch">
        <TextBox x:Name="GroupChatTextBox" VerticalAlignment="Bottom" TextWrapping="Wrap" FontSize="14" Width="140" Height="40" Margin="5,5,5,5" BorderThickness="1" BorderBrush="Gray"/>
        <Button x:Name="SendButton" Content="Send"  
                        HorizontalAlignment="Left" Height="40" 
                        VerticalAlignment="Top" Width="Auto"  
                        Click="SendButton_Click"  Margin="5,5,5,5"
                        BorderThickness="1" BorderBrush="Gray"/>
    </StackPanel>
</StackPanel>