【问题标题】: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 并使用数据触发器安排控件。

标签: c# .net wpf visual-studio xaml


【解决方案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 的,如果我进行一些更改,将很难维护。我仍然需要在它们之间添加边距(一个数字框控制它),文本的框架等。所以我猜我需要尝试像你说的那样制作一个自定义面板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2011-03-30
  • 1970-01-01
相关资源
最近更新 更多