4

我觉得我可能需要一些转换器,但这是我想做的。我想要一个具有以下参数的图像控件(因为它位于绑定到真实数据的数据模板中)。

  • 以 90x90 的空间为中心(没有任何形式的拉伸)。
  • 有一个半径为 40 像素(水平和垂直)的圆形剪裁。
  • 如果图像 > 90x90,它应该在 90x90 空间内居中,并从中间剪裁一个 40x40 的圆圈。
  • 如果图像 < 90x90,它应该在 90x90 空间内居中。由于整个图像都包含在剪辑区域内,因此剪辑圈应该没有效果。

我在下面有我的 XAML 代码。这适用于正好为 90x90 的图片(即它们不拉伸,它们使图像居中并且剪辑工作)。对于 > 90x90 的图像,剪裁工作正常,但图像未居中。对于 < 90x90 的图像,图像居中,但剪裁似乎将图像放置在图像内容的左上角区域,因此剪裁会剪裁图像的左上角部分。

<Style x:Key="ImageStyle">
    <Setter Property="Width" Value="90" />
    <Setter Property="Height" Value="90" />
    <Setter Property="Stretch" Value="None" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="Clip">
        <Setter.Value>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Setter.Value>
    </Setter>
</Style>

<Grid>
    <!-- Other Stuff -->
    <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
</Grid>

我可以通过包裹在 Grid 中并将剪辑移动到那里来摆脱第二个问题(小图像剪辑),但大的东西不会居中:

<Grid>
    <!-- Other Stuff -->
    <Grid Width="90" Height="90">
        <Grid.Clip>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Grid.Clip>
        <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
    </Grid>
</Grid>
4

3 回答 3

10

我最终不得不从图像样式中删除宽度和高度属性。使用 WPF Snoop 查看它,图像现在比包含的 Grid 大,但由于 Grid 具有固定大小,因此它以它为中心。

<Style x:Key="ImageStyle">
    <Setter Property="Stretch" Value="None" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
</Style>

<Grid>
    <!-- Other Stuff -->
    <Grid Width="90" Height="90">
        <Grid.Clip>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Grid.Clip>
        <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
    </Grid>
</Grid>
于 2014-02-19T18:15:38.123 回答
3

我发现居中和剪辑图像的最简单方法是使用不同的元素,例如矩形,然后用 ImageBrush 填充它。例如:

<Rectangle>
    <Rectangle.Fill>
        <ImageBrush
            ImageSource="{Binding SomeUriPropertyOrOther}"
            Stretch="UniformToFill"/>
    </Rectangle.Fill>
</Rectangle>

这会进行居中和裁剪。(我猜,与 Stretch == Fill 和 Uniform 无关。)

于 2015-09-16T14:10:29.747 回答
0

在您的数据模板中使用 ImageBrush。然后你可以画成椭圆,而不是使用剪裁。

XAML

  <Grid>
    <ListBox ItemsSource='{Binding}'>
      <ListBox.ItemTemplate>
        <DataTemplate>

          <Grid Width='90' Height='90' Background='Yellow'>

          <Ellipse Width='40'
                   Height='40'>
            <Ellipse.Fill>
              <ImageBrush ImageSource='{Binding ImagePath}'
                          Stretch='None' />
            </Ellipse.Fill>

          </Ellipse>
          </Grid>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>

代码

public partial class Window4 : Window {
    public Window4() {
      InitializeComponent();

      var data = new List<DemoData>();
      data.Add(new DemoData { Header="Large Image", ImagePath="flower.png"});
      data.Add(new DemoData { Header = "Medium Image", ImagePath = "flower_med.png" });
      data.Add(new DemoData { Header = "Small Image", ImagePath = "flower_small.png" });
      this.DataContext = data;
    }
  }

  internal class DemoData {
    public string Header { get; set; }
    public string ImagePath { get; set; }
  }

结果

带省略号的列表框

于 2014-02-14T08:33:13.840 回答