c# - Adorner as popup not working -


i tried create popup in wpf using adorner can greyout background. idea accept kind of uielement, greyout , lock others (like showdialog in forms), , show uielement.

it based on tutorial website.

i have 1 class called popup:

class popup : adorner, idisposable {     private static readonly brush _screenbrush = new solidcolorbrush(color.fromargb(0x7f, 0x7f, 0x7f, 0x7f));     private static uielement _childelement;     private static window _window;     private adornerlayer _layer;      public static idisposable overlay(uielement childelement)     {         _window = application.current.mainwindow;         var grid = logicaltreehelper.getchildren(_window).oftype<grid>().firstordefault();         var adorner = new popup(grid, childelement) { _layer = adornerlayer.getadornerlayer(grid) };         adorner._layer.add(adorner);         return adorner idisposable;     }      private popup(uielement parentparentelement, uielement childelement)         : base(parentparentelement)     {         _childelement = childelement;          if (childelement != null)         {             addvisualchild(childelement);         }          getfocus(this);     }      protected override int visualchildrencount     {         { return _childelement == null ? 0 : 1; }     }      protected override visual getvisualchild(int index)     {         if (index == 0 && _childelement != null)         {             return _childelement;         }          getfocus(this);         return base.getvisualchild(index);     }         protected override size measureoverride(size constraint)        {            _childelement.measure(constraint);            return _childelement.rendersize;        }         protected override size arrangeoverride(size finalsize)        {            if (_childelement == null) return finalsize;            var adorningpoint = new point(0, 0);            _childelement.arrange(new rect(adorningpoint, this.adornedelement.rendersize));            return finalsize;        }        protected override void onrender(drawingcontext drawingcontext)       {           _screenbrush.opacity = 0.5;           drawingcontext.drawrectangle(_screenbrush, null, windowrect());           base.onrender(drawingcontext);       }      private rect windowrect()     {         if (_window == null)         {             throw new argumentexception("cant main window");         }          var transformtoancestor = this.adornedelement.transformtoancestor(_window);         var windowoffset = transformtoancestor.inverse.transform(new point(0, 0));          // point of lower-right corner of window         var windowlowerright = windowoffset;         windowlowerright.offset(_window.actualwidth, _window.actualheight);         return new rect(windowoffset, windowlowerright);     }      private void getfocus(uielement element)     {         element.focusable = true;         keyboard.focus(element);         element.isenabled = true;     }      public void dispose()     {        _layer.remove(this);     } } 

this class adorner magic , draws uielement on top of first or default grid inside current window.

i created static class popupextender:

 public static class popupextender {     private static dictionary<uielement, idisposable> _popups;              public static void showaspopup(this uielement child)     {         if (_popups == null)         {             _popups = new dictionary<uielement, idisposable>();         }          _popups.add(child, popup.overlay(child));     }      public static void closepopup(this uielement child)     {         if (!_popups.containskey(child)) return;         var disposablechild = _popups[child];         disposablechild.dispose();         _popups.remove(child);     }} 

that uses extension methods allow uielement close , show.

everything seems work ok window (and other elements) can still used keyboard. tried using isenabled = false makes little ugly, i'm trying have same effect showdialog().

second problem when popup opens popup parent freezes , doesn't accept input (nothing does..).

i hope can me. maybe adorners aren't best idea , if has suggestions or better ideas please share.

here simple example of overlay doesn't require adorners.

xaml:

<window x:class="yourapp.mainwindow"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     ... >     <window.resources>         <booleantovisibilityconverter x:key="booleantovisibilityconverter" />     </window.resources>      <!-- define normal xaml here -->      <rectangle fill="#7fffffff" visibility="{binding yourboolproperty,          horizontalalignment="stretch" verticalalignment="stretch"          converter={staticresource booleantovisibilityconverter}}" /> </window> 

in code:

// show overlay yourboolproperty = true; 

...

// hide overlay yourboolproperty = false; 

Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -