首页 > 解决方案 > 拖放不适用于自定义 Window.Style

问题描述

我有一个用 wpf 制作的简单 UI。有一个页面包含一个带有 TreeView 的 CustomControl。要重新排序 TreeNodes,我正在使用 wpf 拖放。到目前为止,这工作得很好。现在我正在使用 WindowChrome 来创建一个无边框窗口。但问题是:现在拖放将不起作用。如果我尝试拖动一个对象,光标将变为“无有效放置位置”

我发现了什么:如果我删除我的自定义,一切正常。但是我现在知道要使拖放功能与我的自定义样式一起使用,还缺少什么。

树视图:

    <TreeView x:Name="StructureTree"
                  Grid.Row="0"
                  Padding="10,20,20,0"
                  VerticalAlignment="Stretch"
                  HorizontalAlignment="Stretch" 
                  ItemsSource="{Binding Path=RootElement.Children}"
                  Background="{x:Null}" 
                  BorderBrush="{x:Null}"
                  dd:DragDrop.IsDragSource="true"
                  dd:DragDrop.IsDropTarget="true"
                  dd:DragDrop.UseDefaultDragAdorner="true">

Window.Resources:

    <Window.Resources>
    <Style TargetType="{x:Type local:MainWindow}" BasedOn="{StaticResource {x:Type Window}}">
     <Setter Property="Template">
                <Setter.Value>
                  <ControlTemplate TargetType="{x:Type Window}">

                        <!-- Outer border with the dropshadow margin -->
                        <Border Padding="{Binding OuterMargin, FallbackValue=10}">

                            <!-- Main window outline -->
                            <Grid>

                                <!-- Opacity mask for corners on grid -->
                                <Border x:Name="Container"
                                        Background="{StaticResource BackgroundVeryLightBrush}"
                                        CornerRadius="{Binding WindowCornerRadius}" />

                                <!-- Window border and dropshadown -->
                                <Border CornerRadius="{Binding WindowCornerRadius}"
                                    Background="{Binding BackgroundVeryLightBrush}" BorderBrush="#FF1E1E1E">
                                    <Border.Effect>
                                        <DropShadowEffect ShadowDepth="2" Opacity="0.2" BlurRadius="5" />
                                    </Border.Effect>
                                    <Border.OpacityMask>
                                        <VisualBrush Visual="{Binding ElementName=Container}" />
                                    </Border.OpacityMask>
                                </Border>

                                <!-- The main window content -->
                                <Grid>

                                    <!-- Corner clipping -->
                                    <Grid.OpacityMask>
                                        <VisualBrush Visual="{Binding ElementName=Container}" />
                                    </Grid.OpacityMask>

                                    <Grid.RowDefinitions>

                                        <!-- Title Bar -->
                                        <RowDefinition Height="{Binding TitleHeight, FallbackValue=42}"/>
                                        <!-- Window Content -->
                                        <RowDefinition Height="*"/>

                                    </Grid.RowDefinitions>

                                    <!-- Title Bar -->
                                    <Grid Grid.Column="0" Grid.Row="0" Panel.ZIndex="1">
                                        <Grid.ColumnDefinitions>

                                            <!-- Icon -->
                                            <ColumnDefinition Width="Auto"/>
                                            <!-- Title -->
                                            <ColumnDefinition Width="*"/>
                                            <!-- Window Buttons -->
                                            <ColumnDefinition Width="Auto"/>

                                        </Grid.ColumnDefinitions>

                                        <!-- Icon -->
                                        <Button Margin="1" Padding="0" Style="{StaticResource IconButton}" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding MenuCommand}">
                                            <!--<Image Source="/Images/Logo/Icon.ico"/>-->
                                        </Button>

                                        <!-- Title -->
                                        <Viewbox Grid.Column="0" Grid.ColumnSpan="3" Margin="0">
                                            <TextBlock Style="{StaticResource TitleText}"                                              
                                                       Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue= 'Wellcome'}"/>
                                        </Viewbox>

                                        <!-- Window Buttons -->
                                        <StackPanel Grid.Column="2" Orientation="Horizontal">
                                            <Button Command="{Binding MinimizeCommand}" Style="{StaticResource WindowControlButton}" Content="_"/>
                                            <Button Command="{Binding MaximizeCommand}" Style="{StaticResource WindowControlButton}" Content="[ ]"/>
                                            <Button Command="{Binding CloseCommand}" Style="{StaticResource WindowCloseButton}" Content="X"/>
                                        </StackPanel>

                                    </Grid>
                                    <!-- Page Content -->
                                    <Border Grid.Row="1" Padding="{Binding InnerContentPadding}">
                                        <ContentPresenter   Content="{TemplateBinding Content}"/>
                                    </Border>
                                </Grid>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

标签: c#wpf

解决方案


当我尝试类似的场景时,我发现如果 WPF 无法检测到光标下的控件,则它不允许删除项目。对此的解决方案可能是在 TreeView 的“下方”添加一个带有透明填充的拉伸矩形:

    <Rectangle
        Fill="Transparent"
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch"/>
    <TreeView x:Name="StructureTree"...

就这样一个控件可以在您的光标“下方”,然后您应该返回您的有效放置区域。

编辑:

如果它不想工作,请尝试将矩形放在模板中此部分之前:

<!-- Opacity mask for corners on grid -->
<Border x:Name="Container"
        Background="{StaticResource BackgroundVeryLightBrush}"
        CornerRadius="{Binding WindowCornerRadius}" />

由于基本窗口模板使用 AdornerDecorator,因此在需要的地方也值得一试:

<AdornerDecorator>
    <ContentPresenter.../>
</AdornerDecorator>

推荐阅读