2014-12-11 9 views
4

Мне очень нравится эффект, который можно увидеть, например, в iOS, который в основном выглядит как слой, нарисованный поверх текущего представления, закрашивая визуальный контент и используя его в качестве фона. Есть ли способ добиться чего-то подобного в WPF?многослойное окно с эффектом размытия

iOS

Я видел, что люди в основном имеем дело с этим размытия/прозрачности на уровне окна, но мне это нужно в окне.

Скажем, это содержимое моего окна.

<StackPanel HorizontalAlignment="Center" Orientation="Horizontal"> 
     <Image Source="pack://application:,,,/Resources/Penguins.jpg"/> 
     <Image Source="pack://application:,,,/Resources/Penguins.jpg"/> 
</StackPanel> 

который выглядит как

No layer

А теперь я хотел бы нарисовать что-нибудь на вершине того, что (вместо того, чтобы использовать красный фон) blures все, что под ним, и использует его в качестве фона , сохраняя его содержание не размытие.

<DockPanel Margin="15" Background="Red"> 
     <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <Label Content="Some label"/> 
      <TextBox Width="100" Height="20"/> 
     </StackPanel> 
    </DockPanel> 

Blur layer

+0

http://jmorrill.hjtcentral.com/Home/ tabid/428/EntryId/403/Glass-Behavior-for-WPF.aspx –

+0

@HighCore Я уже попробовал попробовать прожектор, но кажется, что это скорее стекловидное, чем пятно y effect, havent смог получить желаемый эффект. Я что-то делаю неправильно? – pikausp

+0

Вы можете применять любые эффекты в поведении. Просто примените «BlurEffect» с правильным BlurRadius, и вам хорошо идти. –

ответ

4

Результат:

WPF with blurred background

  • Мы будем использовать иерархическое в сетке. Предыстория: ваш основной контент приложения. Foreground: ваш псевдодиалог, который будет иметь размытый фон.

  • Мы помещаем фон в рамку и ссылаемся на эту границу по ее названию. Это будет использоваться в VisualBrush и обеспечить наше размытое изображение.

  • На переднем плане также будет многоуровневая сетка. Фон: прямоугольник, заполненный кистью и использующий эффект размытия. Передний план: все, что вы хотите быть впереди.

    1. Добавить ссылку на System.Windows.Interactivity.

    2. Добавьте следующий код поведения:

      using System; 
      using System.Collections.Generic; 
      using System.Linq; 
      using System.Windows; 
      using System.Windows.Controls; 
      using System.Windows.Data; 
      using System.Windows.Interactivity; 
      using System.Windows.Media; 
      using System.Windows.Media.Effects; 
      using System.Windows.Shapes; 
      
      namespace WpfApplication1 
      { 
          public class BlurBackgroundBehavior : Behavior<Shape> 
          { 
           public static readonly DependencyProperty BlurContainerProperty 
            = DependencyProperty.Register(
                    "BlurContainer", 
                    typeof (UIElement), 
                    typeof (BlurBackgroundBehavior), 
                    new PropertyMetadata(OnContainerChanged)); 
      
           private static readonly DependencyProperty BrushProperty 
            = DependencyProperty.Register(
                    "Brush", 
                    typeof (VisualBrush), 
                    typeof (BlurBackgroundBehavior), 
                    new PropertyMetadata()); 
      
           private VisualBrush Brush 
           { 
            get { return (VisualBrush) this.GetValue(BrushProperty); } 
            set { this.SetValue(BrushProperty, value); } 
           } 
      
           public UIElement BlurContainer 
           { 
            get { return (UIElement) this.GetValue(BlurContainerProperty); } 
            set { this.SetValue(BlurContainerProperty, value); } 
           } 
      
           protected override void OnAttached() 
           { 
            this.AssociatedObject.Effect = new BlurEffect 
                    { 
                     Radius = 80, 
                     KernelType = KernelType.Gaussian, 
                     RenderingBias = RenderingBias.Quality 
                    }; 
      
            this.AssociatedObject.SetBinding(Shape.FillProperty, 
                    new Binding 
                    { 
                     Source = this, 
                     Path = new PropertyPath(BrushProperty) 
                    }); 
      
            this.AssociatedObject.LayoutUpdated += (sender, args) => this.UpdateBounds(); 
            this.UpdateBounds(); 
           } 
      
           protected override void OnDetaching() 
           { 
            BindingOperations.ClearBinding(this.AssociatedObject, Border.BackgroundProperty); 
           } 
      
           private static void OnContainerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
           { 
            ((BlurBackgroundBehavior) d).OnContainerChanged((UIElement) e.OldValue, (UIElement) e.NewValue); 
           } 
      
           private void OnContainerChanged(UIElement oldValue, UIElement newValue) 
           { 
            if (oldValue != null) 
            { 
             oldValue.LayoutUpdated -= this.OnContainerLayoutUpdated; 
            } 
      
            if (newValue != null) 
            { 
             this.Brush = new VisualBrush(newValue) 
                { 
                 ViewboxUnits = BrushMappingMode.Absolute 
                }; 
      
             newValue.LayoutUpdated += this.OnContainerLayoutUpdated; 
             this.UpdateBounds(); 
            } 
            else 
            { 
             this.Brush = null; 
            } 
           } 
      
           private void OnContainerLayoutUpdated(object sender, EventArgs eventArgs) 
           { 
            this.UpdateBounds(); 
           } 
      
           private void UpdateBounds() 
           { 
            if (this.AssociatedObject != null && this.BlurContainer != null && this.Brush != null) 
            { 
             Point difference = this.AssociatedObject.TranslatePoint(new Point(), this.BlurContainer); 
             this.Brush.Viewbox = new Rect(difference, this.AssociatedObject.RenderSize); 
            } 
           } 
          } 
      } 
      
    3. использовать его в XAML как это:

      <Grid> 
      
          <Border x:Name="content"> 
           <Border.Background> 
            <ImageBrush ImageSource="bild1.jpg" /> 
           </Border.Background> 
      
           <StackPanel> 
            <TextBox Width="200" Margin="10" /> 
            <TextBox Width="200" Margin="10" /> 
            <TextBox Width="200" Margin="10" /> 
           </StackPanel> 
          </Border> 
      
          <Grid Margin="59,63,46,110"> 
      
           <Rectangle ClipToBounds="True"> 
            <i:Interaction.Behaviors> 
             <wpfApplication1:BlurBackgroundBehavior BlurContainer="{Binding ElementName=content}" /> 
            </i:Interaction.Behaviors> 
           </Rectangle> 
      
           <TextBox VerticalAlignment="Center" Text="Blah" Width="200" Height="30" /> 
      
          </Grid> 
      
      </Grid> 
      
+0

Что означает 'i' как? – pikausp

+0

Просто понял, спасибо большое Фрэнку, это именно то, что мне нужно, спасибо Фрэнку! – pikausp

+0

На самом деле я только что заметил вопрос о производительности, когда я пытаюсь изменить размер формы, может ли это быть избавлено? – pikausp