在Win8 Metro App中动态创建可拖动的UserControl

时间:2013-12-09 16:57:33

标签: c# xaml windows-runtime microsoft-metro datatemplate

此时我有一个视图,它使用绑定到用户列表的切片填充ListView。 OnClick任何这些Tiles(按钮)我需要动态创建一个小的可拖动窗口,其中包含一个包含ScrollViewer& ItemsControl,Textbox和Button的StackPanel。然后必须根据单击的用户Tile绑定到ObservableCollection。

这将用于私人聊天方案。

我已经实现了绑定到ObservableCollection的群聊,但这是在导航到页面时创建的。

我已经开始将一组相同的控件添加到一个dataTemplate到Resources.xaml,但我很遗憾下一步该去哪里。

<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>

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

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

在您的网页中 - 将ScrollViewer扩展到应用窗口的完整大小(通过将VerticalAlignmentHorizontalAlignment都设置为Stretch), Panel内部有CanvasGrid,并将窗口/ UserControl放在其中 - 就像下面代码中的Rectangle一样。通过将ScrollViewer值和面板大小设置为大于-ScrollMode/-ScrollBarVisibility ScrollViewer'sViewportWidth,确保ViewportHeight可以双向滚动。您应该在SizeChanged及其内部窗口处理ScrollViewer事件,并将面板的WidthHeight设置为类似

panel.Width = scrollViewer.ViewportWidth * 2 - window.ActualWidth;
panel.Height = scrollViewer.ViewportHeight * 2 - window.ActualWidth;

现在一切都应该通过触摸滚动。剩下的问题是处理鼠标输入,您可以根据窗口上的Pointer-事件进行操作。

<强> 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>

<强> C#     使用Windows.Devices.Input;     使用Windows.Foundation;     使用Windows.UI.Xaml;     使用Windows.UI.Xaml.Controls;     使用Windows.UI.Xaml.Input;

namespace DraggableWindow
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private uint pointerId;
        private Point lastPoint;

        private void OnWindowPointerPressed(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse)
            {
                window.CapturePointer(e.Pointer);
                this.pointerId = e.Pointer.PointerId;
                this.lastPoint = e.GetCurrentPoint(window).Position;
            }
        }

        private void OnWindowPointerMoved(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.IsInContact &&
                e.Pointer.PointerId == pointerId)
            {
                var point = e.GetCurrentPoint(window).Position;
                this.scrollViewer.ChangeView(
                    this.scrollViewer.HorizontalOffset - point.X + lastPoint.X,
                    this.scrollViewer.VerticalOffset - point.Y + lastPoint.Y,
                    null,
                    true);
            }
        }

        private void OnWindowPointerReleased(object sender, PointerRoutedEventArgs e)
        {
            if (e.Pointer.PointerId == pointerId)
            {
                window.ReleasePointerCapture(e.Pointer);
            }
        }

        private void OnScrollViewerSizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateWindowingLayout();
        }

        private void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            UpdateWindowingLayout();
        }

        private void UpdateWindowingLayout()
        {
            this.panel.Width = this.scrollViewer.ViewportWidth * 2 - 0.0 * this.window.ActualWidth;
            this.panel.Height = this.scrollViewer.ViewportHeight * 2 - 0.5 * this.window.ActualHeight;
            Canvas.SetLeft(this.window, this.scrollViewer.ViewportWidth - 0.5 * this.window.ActualWidth);
            Canvas.SetTop(this.window, this.scrollViewer.ViewportHeight - 0.5 * this.window.ActualHeight);
        }
    }
}

哦,并使其全部动态 - 将其包装在UserControl中以处理那里的事件并将其放在Popup中。当我有机会时,我会看到将所有这些包装在一个可重用的控件中,因为我的视觉树调试器覆盖也需要类似的东西。

答案 1 :(得分:0)

@Filip Skakun不幸的是我必须使用8.0而不是8.1,所以没有新的ChangeView方法。我试图制作一个自定义的UserControl,但我不知道如何处理SizeChanged和UpdateWindowingLayout,因为Windows将基本上通过点击按钮创建并动态创建。然后我需要将一个字符串列表绑定到UserControl中的ItemsControl `不幸的是我必须使用8.0而不是8.1,所以不要使用新的ChangeView方法。我试图制作一个自定义的UserControl,但我不知道如何处理SizeChanged和UpdateWindowingLayout(实现拖动),因为将在点击基本上动态创建的按钮创建窗口。然后我需要将一个字符串列表绑定到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>