如何在文本块周围设置图像位置
Posted
技术标签:
【中文标题】如何在文本块周围设置图像位置【英文标题】:How to set image placement around a textblock 【发布时间】:2021-10-20 21:31:23 【问题描述】:我是 C# 和 wpf 的新手,所以如果这是一个愚蠢的问题,请不要批评。
我在 DockPanel 中有 Image 和 TextBlock,然后我有一个 ComboBox,用于控制图像在文本周围的显示位置。 ComboBox 项是(“文本左侧”、“文本右侧”、“文本上方”、“文本下方”、“中心”)
我可以通过绑定 DockPanel.Dock 来进行左、右、上和下操作,但是对于中心,我需要将图像放在文本后面(覆盖它们),而 DockPanel 不允许我这样做。我想使用 Canvas,但出于其他原因(文本换行问题等)特别要求我不要使用。
现在我只需要在从组合框中选择“中心”时覆盖图像和文本。
xaml
<DockPanel>
<Image Source="Binding Path=ImageSource, UpdateSourceTrigger=PropertyChanged" DockPanel.Dock="Binding Path=ImagePlacementDisplay, UpdateSourceTrigger=PropertyChanged"/>
<TextBlock TextWrapping="WrapWithOverflow" Text="Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged" />
查看模型
public string SelectedImagePlacement
get return _ex2.ImagePlacement;
set
_ex2.ImagePlacement = value;
OnPropertyChanged("SelectedImagePlacement");
OnPropertyChanged("ImagePlacementDisplay");
public string ImagePlacementDisplay
get
switch (SelectedImagePlacement)
case "0":
return "Left";
case "1":
return "Right";
case "2":
return "Top";
case "3":
return "Bottom";
case "4":
return "Center"; //not working
default:
return "Right";
set
OnPropertyChanged("ImagePlacementDisplay");
【问题讨论】:
您忘记显示 xaml。 z 顺序与子面板的顺序相同,先放Image
,然后是TextBox
,后者将在上方。或者您可以使用ZIndex 进行更改。
@Sinatr 我包含了我的代码的 sn-ps,但我不确定它是否有帮助,或者它只是让我的问题更加混乱。我尝试使用 Panel.ZIndex,但这不仅仅是我想要的。
所以您希望两个控件都为occupy the middle 并重叠?您可以使用自定义枚举制作自己的面板来控制对齐。或者您可以忘记DockPanel
,使用Grid
并使用数据触发器安排控件。
【参考方案1】:
您可以使用数据触发器来修改控制位置。
下面是 2x2 Grid
,根据 ComboBox.SelectedIndex
的值,数据触发器将安排 Image
(用黄色网格模拟)和 TextBlock
的位置。
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="Yellow">
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="0">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="1" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="1">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="1" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="1" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="2">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="1" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="3">
<Setter Property="Grid.Row" Value="1" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="1" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="4">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
<TextBlock Text="Bla bla bla" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="0">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="1" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="1" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="1">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="1" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="2">
<Setter Property="Grid.Row" Value="1" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="1" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="3">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="1" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
<DataTrigger Binding="Binding SelectedIndex, ElementName=combobox" Value="4">
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.RowSpan" Value="2" />
<Setter Property="Grid.ColumnSpan" Value="2" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ComboBox x:Name="combobox" VerticalAlignment="Bottom" Grid.Row="1" SelectedIndex="0">
<ComboBoxItem Content="Left"/>
<ComboBoxItem Content="Right"/>
<ComboBoxItem Content="Up"/>
<ComboBoxItem Content="Down"/>
<ComboBoxItem Content="Center"/>
</ComboBox>
</Grid>
演示:
它可能不是最好看的解决方案,但它展示了数据触发器的强大功能,并且可能会教你一些布局(wpf 中非常重要的技能)。
更好的方法是使用枚举类型的自定义依赖属性创建自定义Panel
来控制子排列。
【讨论】:
感谢您提供替代方案。但是这种方法是硬连线到 UI 的,如果我进行一些更改,将很难维护。我仍然需要在它们之间添加边距(一个数字框控制它),文本的框架等。所以我猜我需要尝试像你说的那样制作一个自定义面板。以上是关于如何在文本块周围设置图像位置的主要内容,如果未能解决你的问题,请参考以下文章