2014-02-13 2 views
3

Я чувствую, что мне могут понадобиться некоторые преобразователи, но это то, что я хочу сделать. Мне нужен один элемент управления Image (поскольку он находится в шаблоне данных, привязанный к реальным данным) со следующими параметрами.Хост изображения WPF с центрированием и обрезкой

  • Будьте центрированы в пространстве, которое составляет 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> 
    <!-- 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> 

ответ

5

Мне пришлось просто удалить свойства Width и Height из стиля изображения. Посмотрев на него с помощью WPF Snoop, изображение теперь больше, чем содержащая 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> 
+0

Благодарим за такое приятное решение – Sayka

0

Используйте ImageBrush в ваш Datatemplate. Затем вы можете нарисовать Эллипс и не использовать обрезку.

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; } 
    } 

Результат

ListBox with ellipses

1

Самый простой способ я нашел в центре и клип и изображения использовать другой элемент, такой как прямоугольник, а затем заполнить его с ImageBrush. Например:

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

Это центровка и отсечение. (Не подходит для растяжки == Заполнения и формы, я думаю.)

+0

Спасибо! Это помогло – Val

Смежные вопросы