好的,我有一个包含容器控件的 ListBox。每个容器控件都包含 1-X 小部件,这些小部件布置在完全自定义的 WrapPanel 中,效果很好。小部件的大小由 2 个因素确定/更新:
- 父列表框的大小(如果更改则更新)
- 视图比例 SliderBar (25%, 50%, 100%) - 就像一个缩放按钮
如果更改列表框大小,自定义面板重绘和小部件大小在我的代码中相应调整。工作完美。
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="5" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Name="lstGroups" Grid.Column="0" ItemsSource="{Binding Path=TopLevelGroups}" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Hidden" SizeChanged="ListBox_SizeChanged" VerticalAlignment="Stretch"
SelectionMode="Extended"
Style="{ StaticResource ListBoxWithAutoScroll_Horizontal }"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<StackPanel Grid.Row="2" HorizontalAlignment="Left" VerticalAlignment="Center" Orientation="Horizontal">
<Label Margin="5">View Scale:</Label>
<Slider Name="sldView" Minimum="25" Maximum="100" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="25,50,100" Width="125" ValueChanged="Slider_ValueChanged"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Right" DockPanel.Dock="Right">
<Button Command="{Binding Path=StopCommand}" Content="Stop" Height="30" Width="60" Margin="1" IsEnabled="{Binding Path=CanStop}" x:Name="btnStop" />
<Button Command="{Binding Path=RunCommand}" Content="Run" Height="30" Width="60" IsEnabled="{Binding Path=CanRun}" x:Name="btnRun" HorizontalAlignment="Right" Margin="1"/>
</StackPanel>
--小部件--
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Edit" Command="{Binding Path=EditCommand}" IsEnabled="{Binding IsMonitorStopped}"/>
<MenuItem Header="Remove" Command="{Binding Path=RemoveCommand}" IsEnabled="{Binding IsMonitorStopped}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="" Margin="2" />
<Label Content="{Binding Path=Name}" Margin="5,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
<ItemsControl Grid.Row="1" ItemsSource="{Binding Path=Entities}" Name="icEntities" >
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type vm:AppleViewModel}">
<ct:AppleTile Height="{Binding Path=AppleHeight}" Width="{Binding Path=AppleWidth}" Grid.ColumnSpan="2" Grid.RowSpan="2"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:OrangeViewModel}">
<ct:OrangeTile Height="{Binding Path=OrangeHeight}" Width="{Binding Path=OrangeWidth}" Grid.ColumnSpan="2"/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:GrapeViewModel}">
<ct:GrapeTile Height="{Binding Path=GrapeHeight}" Width="{Binding Path=GrapeWidth}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- Custom Wrap panel -->
<co:MonitorPanel x:Name="mpMain"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
如果用户移动滑块进行放大/缩小 - 我需要能够强制自定义面板使用新计算的小部件尺寸重新渲染。
private void ListBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
//Works perfect
this.ResetViewScale(e.NewSize);
}
...麻烦来了:
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
...code here
this.ResetViewScale(new Size(this.myListBox.ActualWidth, this.myListBox.ActualHeight));
//How can I repaint my list/panel?
}
private void ResetViewScale(Size e)
{
Size newSize = new Size(e.Height / 2, e.Height / 2);
switch (App.ApplicationViewScale)
{
case ViewScale.Full:
Size full = new Size(newSize.Height, newSize.Height);
App.TileSize = new Size(full.Height, full.Width);
break;
case ViewScale.Half:
Size half = new Size(newSize.Height / 2, newSize.Height / 2);
App.TileSize = new Size(half.Height, half.Width);
break;
case ViewScale.Quarter:
Size quarter = new Size(newSize.Height / 4, newSize.Height / 4);
App.TileSize = new Size(quarter.Height, quarter.Width);
break;
default:
Size defaultToFull = new Size(newSize.Height, newSize.Height);
App.TileSize = new Size(defaultToFull.Height, defaultToFull.Width);
break;
}
}
我尝试使用所有 Invalidate 方法,但似乎没有任何效果。有点卡住了...