【发布时间】:2018-05-22 19:10:22
【问题描述】:
<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid
Grid.IsSharedSizeScope ="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Visible">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<RadioButton
Name="RadioButton"
Grid.Column="0"
Margin="16"
VerticalAlignment="Center"
IsChecked="False" />
<TextBlock
Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontFamily="{StaticResource RRWFont}"
FontSize="{Binding FontSize, ElementName=TextBlock}"
Foreground="{StaticResource DarkGrey}"
Text="{Binding Path=Content.Name}"
TextAlignment="Left"
TextWrapping="Wrap" />
</Grid>
<Image
Grid.Row="1"
Width="auto"
Height="auto"
Source="{Binding Path=Content.File}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="RadioButton" Property="IsChecked" Value="True" />
</Trigger>
<Trigger SourceName="RadioButton" Property="IsChecked" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
XAML(列表框)
<ListBox
Grid.Column="1"
HorizontalAlignment="Center"
Background="{x:Null}"
BorderBrush="{x:Null}"
ItemContainerStyle="{StaticResource ListBoxItemStyle}"
ItemsSource="{Binding Path=AnswersVariants}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedItem="{Binding Path=SelectAnswer, Mode=TwoWay}"
SelectionMode="Single">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Loaded="ListBoxWrapPanel_Loaded"
Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
C#
private void ListBoxWrapPanel_Loaded(object sender, RoutedEventArgs e)
{
if (!(sender is WrapPanel panel))
return;
if (panel.Children.Count == 0)
return;
var max = (from FrameworkElement panelChild in panel.Children
select panelChild.ActualWidth + panelChild.Margin.Left + panelChild.Margin.Right)
.Concat(new double[] { 0 }).Max();
panel.ItemWidth = max;
}
我有这个 ContentControl:(类名已更改)
*XAML:*
ContentControl
Content="{Binding CurrentContent}"
I change the CurrentContent like this:
CurrentContent = new ContentOne();
CurrentContent = new ContentTwo();
为 MVVM 创建了 INotifyPropertyChanged 等,并且一切正常 正确。
有这样的问题。当一个 CurrentContent 更改为另一个时, 但同一个类,视图没有改变,它只改变了 数据。
那些。
CurrentContent = new ContentOne(); //1
---over time
CurrentContent = new ContentOne(); //2
在第二种情况下,视图保持不变。
这会导致一个问题,因为在View中有一个ListBox,ItemPanel 它代表 WrapPanel。对于所有 WP 儿童,身高和 宽度是相同的,并在视图的初始化过程中设置 通过找到最大的宽度和高度。当 ViewModel 变化,但视图不变,可能会发生以下情况:
您将无法重新计算高度和宽度,因为它们 当它们尚未为 WrapPanel 设置时,将被考虑,并且在 * 2 的情况下,它们已经设置好了。
附:在这种情况下,一切正常:
CurrentContent = new ContentOne();
---over time
CurrentContent = new ContentTwo();
---over time
CurrentContent = new ContentOne();
【问题讨论】:
-
“高度和宽度是相同的,并且是在 View 的初始化过程中通过查找最大宽度和高度来设置的” -- 您的 XAML 已损坏。不要那样设置宽度和高度。您后面的代码应该完全没有用于布局、对齐、宽度等的代码。您可以使用 WPF 布局技术(如 Grids、HorizontalAlignment、VerticalAlignment 等)来完成所有这些工作,因此它会在需要时自动更新。如果您向我们展示有问题的 XAML,我们可以帮助您修复它,这样就不会出现问题。
-
如果您绝对无法编写正确的 XAML,请创建一个 DataContextChanged 事件处理程序并从那里调用您的布局代码。
-
请发布您的实际代码。你在寻求帮助,但你每一步都在与我作斗争。
-
我找到了解决方案。您需要使用 UniformGrid,而不是 WrapPanel。更感谢你,尽管我的不足,你试图帮助我! :-)
-
太棒了!在 WPF 中,几乎总有一种简单的方法可以让布局按照您的意愿行事,而无需任何代码。