我想阻止一个按钮(ButtonExpander)在点击后移动到ListBox的视口之外,直到它再次被点击。按钮的父级必须是可见的(有足够的空间用于按钮),按钮不能离开它所属的用户控件的边界。如果不满足其中任何一个条件,则按钮将恢复其正常行为。关于如何最好地实现这一点的任何想法?
MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="WinMain"
x:Class="MainWindow"
Title="Window"
Height="500"
Width="680"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
Margin="0"
MaxWidth="700">
<Window.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0.27"/>
<GradientStop Color="#FF2E2E2E" Offset="0.105"/>
<GradientStop Color="#FF1D1D1D" Offset="1"/>
<GradientStop Color="Black" Offset="0.91"/>
</LinearGradientBrush>
</Window.Background>
<Grid x:Name="GridMain">
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="40" MaxHeight="40" MinHeight="40"/>
<RowDefinition/>
<RowDefinition Height="34" MinHeight="34" MaxHeight="34"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Menu" Grid.Row="0" Fill="#FF5F5F5F"/>
<Rectangle x:Name="SomeButtons" Grid.Row="1" Fill="#FF303243"/>
<ListBox x:Name="LbFancy"
Margin="10"
Grid.Row="2"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="False"
Focusable="False"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}">#00000000</SolidColorBrush>
</ListBox.Resources>
</ListBox>
<Rectangle x:Name="Status" Grid.Row="3" Fill="#FF303243"/>
</Grid>
</Window>
MainWindow.vb
Class MainWindow
Dim CurrentMapArray() As String = {"01_FooBar", "02_BarFoo", "03_OofRab", "04_Rab_Oof", "07_Santa", "08_Cat"}
Public Sub New()
'This call is required by the designer
InitializeComponent()
End Sub
Private Sub Build()
'All Maps item
Dim mapinfodef As MapInfo = New MapInfo
LbFancy.Items.Add(mapinfodef)
LbFancy.Items.GetItemAt(0)
mapinfodef.MapTitleInternal.Text = ""
mapinfodef.MapTitle.Text = "All Maps"
For Each map As String In CurrentMapArray
Dim mapinfotemp As MapInfo = New MapInfo
'Set basic values for element properties, etc
LbFancy.Items.Add(mapinfotemp)
Next
End Sub
Private Sub Main() Handles WinMain.Loaded
Build()
End Sub
End Class
ListBox通过后面的代码填充以下用户控件的几十个副本:
MapInfo.xaml
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MapInfo"
x:Name="Mapinfo"
Margin="0,2,3,0"
MinWidth="600"
MinHeight="77">
<Grid x:Name="GridRoot" Height="77" Background="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="563"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="MapCanvas">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="112" Width="Auto"/>
<ColumnDefinition MinWidth="451" Width="451"/>
<ColumnDefinition MinWidth="36" MaxWidth="36"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25" MaxHeight="25"/>
<RowDefinition Height="25" MaxHeight="25"/>
<RowDefinition Height="25" MaxHeight="25"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Height="62"
Width="102"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
BorderBrush="White"
Margin="5,6,0,6"
HorizontalAlignment="Left"
VerticalAlignment="Center"
CornerRadius="1"
BorderThickness="1">
</Border>
<TextBlock x:Name="MapTitle"
Text="Map Title"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="White"
Margin="10,0.725,0,0.725"
FontSize="36"
Grid.Row="0"
Grid.RowSpan="2"
Panel.ZIndex="2"/>
<TextBlock x:Name="MapTitleInternal"
Text="##_MapTitle"
Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="White"
Margin="10,4.354,0,4.353"
Panel.ZIndex="1"/>
<Grid x:Name="MapInfoExt"
Grid.Row="3"
Grid.RowSpan="2"
Grid.ColumnSpan="2"
Width="559"
Panel.ZIndex="2">
<Grid.Background>
<SolidColorBrush Color="#00000000" Opacity="0"/>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Item1" Grid.Row="0" Height="100" Fill="Red" Opacity="0.15"/>
<Rectangle x:Name="Item2" Grid.Row="1" Height="201" Fill="Green" Opacity="0.15"/>
<Rectangle x:Name="Item3" Grid.Row="2" Height="182" Fill="Blue" Opacity="0.15"/>
</Grid>
</Grid>
<Grid x:Name="MapPanel"
Margin="0,1,1,0"
MinHeight="73"
MinWidth="35"
MaxWidth="35"
Grid.Column="1"
Panel.ZIndex="1">
<Grid.Background>
<LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
<GradientStop Color="Black" Offset="1"/>
<GradientStop Color="#FF5F5F5F" Offset="0.5"/>
<GradientStop Color="Black"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MaxHeight="30" MinHeight="30"/>
<RowDefinition Height="Auto" MaxHeight="8" MinHeight="8"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox VerticalAlignment="Top"
Panel.ZIndex="1"
Grid.Row="0"
BorderThickness="0.5"
Margin="0,9,0,0"
HorizontalAlignment="Center"/>
<Rectangle Stroke="Black"
Panel.ZIndex="2"
Grid.Row="0"
Margin="0,-1,0,1"
Grid.RowSpan="3"/>
<Button x:Name="ButtonExpander"
Panel.ZIndex="1"
Click="ButtonExpand_Click"
Grid.Row="2"
VerticalAlignment="Bottom"
Height="24"
Width="24"
VerticalAlignment="Top"
Margin="5"/>
</Grid>
<Border x:Name="MapBorder"
BorderThickness="1"
BorderBrush="#FF0E363C"
UseLayoutRounding="False"
RenderTransformOrigin="0.5,0.5"
Grid.ColumnSpan="2"
Grid.Column="0"
Grid.RowSpan="2"
Margin="0"
Panel.ZIndex="1"/>
</Grid>
</UserControl>
MapInfo.vb
Imports System.Windows.Controls
Public Class MapInfo
Inherits UserControl
Dim _expanded As Boolean = False
Private Sub ButtonExpand_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
If _expanded = True Then
_expanded = False
GridRoot.Height = 77
MapBorder.Tag = ""
Dim rotateTransform1 As New RotateTransform(0)
rotateTransform1.CenterX = 12
rotateTransform1.CenterY = 12
ButtonExpander.RenderTransform = rotateTransform1
Return
Else
_expanded = True
GridRoot.Height = 1545
MapBorder.Tag = "Expanded"
Dim rotateTransform1 As New RotateTransform(180)
rotateTransform1.CenterX = 12
rotateTransform1.CenterY = 12
ButtonExpander.RenderTransform = rotateTransform1
Return
End If
End Sub
End Class
ButtonExpander设置单击时GridRoot的高度。网格可以变得很大,所以点击按钮后,我希望它在ListBox中保持可见,并向上/向下滑动窗口右侧的灰色区域。基本上与本网页右侧的黄色框(类似问题,格式化帮助等)或jQuery插件(如this(社交窗口小部件)相同的交易。
我能找到的与C#/ VB.NET相关的唯一类似问题是this one,但答案并没有真正帮助 - 一个用于WinPhone,我无法查看任何代码,另一个答案是滚动查看器,但我不知道如何使用ListBox。
我会感激任何帮助,不一定要花哨。
答案 0 :(得分:1)
根据您的扩展说明,没有优雅的方法可以做到这一点。一个能让你接近的解决方案如下。
在MapInfo控件xaml中,从当前位置移除按钮,并将带有按钮的画布添加到GridRoot的末尾,如下所示。
<Border x:Name="MapBorder" BorderThickness="1" BorderBrush="#FF0E363C" UseLayoutRounding="False" RenderTransformOrigin="0.5,0.5" Grid.ColumnSpan="2" Grid.Column="0" Grid.RowSpan="2" Margin="0" Panel.ZIndex="1" />
<Canvas Grid.ColumnSpan="2" Background="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Panel.ZIndex="1">
<Button x:Name="ButtonExpander" Panel.ZIndex="1" Click="ButtonExpand_Click" Height="24" Width="24" Margin="5" Canvas.Right="10" Canvas.Top="24" />
</Canvas>
这将允许您将按钮放在MapInfo控件中。
在MainWindow xaml中,处理ScrollView.ScrollChanged事件
<ListBox x:Name="LbFancy"
Margin="10"
Grid.Row="2"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="False"
ScrollViewer.ScrollChanged="ScrollViewer_OnScrollChanged"
Focusable="False"
VerticalAlignment="Center"
HorizontalAlignment="Center">
然后在ScrollViewer_OnScrollChanged事件处理程序中,使用
等代码管理控件中按钮的位置Private Sub ScrollViewer_OnScrollChanged(ByVal sender As Object, ByVal e As ScrollChangedEventArgs)
For Each item As MapInfo In LbFancy.Items
If (item.Expanded) Then
Dim positionTransform = item.TransformToAncestor(LbFancy)
Dim itemPosition = positionTransform.Transform(New Point(0, 0))
If ((itemPosition.Y > 0) And (itemPosition.Y < e.ViewportHeight)) Then
' The top of the item is visible
ElseIf ((itemPosition.Y < 0) And (itemPosition.Y + item.ActualHeight - button.Height > 0)) Then
' the top of the item is not visible but a part of the item is
Dim button = CType(item.FindName("ButtonExpander"), Button)
Canvas.SetTop(button, 0 - itemPosition.Y)
End If
End If
Next
End Sub
在控件创建和滚动过程中,按钮的定位还有很多工作要做,但这应该可以让你开始。
注意:为简洁起见,已删除异常处理和空检查。
我希望这会有所帮助。