本文不讨论Silverlight全屏模式的实现,有关实现这个,可以参考TerryLee的这篇文章,核心代码就是这行:

Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;

本文要讨论的是Silverlight的局部元素全屏,即Element部分全屏。我们在做Silverlight项目中有时候客户有这种需求:希望放大界面的局部,比如一个列表面板啥的,而不是整个界面全屏。如下图:

2011-08-19 16h14_04

实现部分全屏

实现起来也是比较简单,主要思路是用Popup实现弹出全屏,把需要全屏的元素放到容器里并设置为屏幕大小,然后整体实现全屏;当用户退出全屏的时候需要把元素恢复回原位置。好,我们写一个ElementsFullScreenProvider类,实现一个UIElement的扩展方法即可。

 2011-08-19 16h32_28

 

主要实现类:ElementsFullScreenProvider

 1:  
 2: #region "Using Namespace"
 3:  
 4: using System;
 5: using System.Windows;
 6: using System.Windows.Controls;
 7: using System.Windows.Controls.Primitives;
 8:  
 9: #endregion
 10:  
 11: namespace ElementFullScreen
 12: {
 13:  /// <summary>
 14:  /// Make partial UI elements full screen
 15:  /// Provider features:
 16:  /// make UI element full screen
 17:  /// exit full screen and restore UI element
 18:  /// support UIElement.ToggleElementFullScreen -- extension methods
 19:  /// </summary>
 20:  public static class ElementsFullScreenProvider
 21:  {
 22:  #region Members
 23:  static readonly Popup PopupContainer;
 24:  static readonly Panel PopupContentContainer;
 25:  static ElementController _lastElementController; 
 26:  #endregion
 27:  
 28:  #region ElementController
 29:  class ElementController
 30:  {
 31:  double _height = double.NaN;
 32:  double _width = double.NaN;
 33:  int _lastPanelPosition;
 34:  bool _lastPopupIsOpen;
 35:  readonly DependencyObject _parent;
 36:  Thickness? _margin;
 37:  
 38:  public UIElement Element { get; private set; }
 39:  
 40:  public ElementController(UIElement element)
 41:  {
 42:  Element = element;
 43:  
 44:  var elem = element as FrameworkElement;
 45:  if (elem != null && elem.Parent != null)
 46:  {
 47:  _parent = elem.Parent;
 48:  }
 49:  }
 50:  
 51:  public void BringElementToFullScreen()
 52:  {
 53:  TryAction<FrameworkElement>(Element, f =>
 54:  {
 55:  _height = f.Height;
 56:  _width = f.Width;
 57:  
 58:  f.Height = double.NaN;
 59:  f.Width = double.NaN;
 60:  });
 61:  
 62:  TryAction<Control>(Element, f =>
 63:  {
 64:  _margin = f.Margin;
 65:  
 66:  f.Margin = new Thickness(0);
 67:  });
 68:  
 69:  if (_parent != null)
 70:  {
 71:  if (!TryAction<Panel>(_parent, p => { _lastPanelPosition = p.Children.IndexOf(Element); p.Children.RemoveAt(_lastPanelPosition); }))
 72:  if (!TryAction<ContentControl>(_parent, c => c.Content = null))
 73:  if (!TryAction<UserControl>(_parent, u => u.Content = null))
 74:  TryAction<Popup>(_parent, p => { _lastPopupIsOpen = p.IsOpen; p.Child = null; });
 75:  }
 76:  }
 77:  
 78:  public void ReturnElementFromFullScreen()
 79:  {
 80:  TryAction<FrameworkElement>(Element, f =>
 81:  {
 82:  f.Height = _height;
 83:  f.Width = _width;
 84:  });
 85:  
 86:  TryAction<Control>(Element, f =>
 87:  {
 88:  if (_margin.HasValue)
 89:  {
 90:  f.Margin = _margin.Value;
 91:  }
 92:  });
 93:  
 94:  if (_parent != null)
 95:  {
 96:  if (!TryAction<Panel>(_parent, p => p.Children.Insert(_lastPanelPosition, Element)))
 97:  if (!TryAction<ContentControl>(_parent, c => c.Content = Element))
 98:  if (!TryAction<UserControl>(_parent, u => u.Content = Element))
 99:  TryAction<Popup>(_parent, p => { p.Child = Element; p.IsOpen = _lastPopupIsOpen; });
 100:  }
 101:  }
 102:  
 103:  static bool TryAction<T>(object o, Action<T> action)
 104:  where T : class
 105:  {
 106:  T val = o as T;
 107:  
 108:  if (val != null)
 109:  {
 110:  action(val);
 111:  return true;
 112:  }
 113:  
 114:  return false;
 115:  }
 116:  }
 117:  #endregion
 118:  
 119:  #region FullscreenElementID Attached Property
 120:  
 121:  static readonly DependencyProperty FullscreenElementIDProperty = DependencyProperty.RegisterAttached(
 122:  "FullscreenElementID", typeof(Guid?), typeof(ElementsFullScreenProvider), new PropertyMetadata(null));
 123:  
 124:  static void SetFullscreenElementID(DependencyObject obj, Guid? value)
 125:  {
 126:  obj.SetValue(FullscreenElementIDProperty, value);
 127:  }
 128:  
 129:  static Guid? GetFullscreenElementID(DependencyObject obj)
 130:  {
 131:  return (Guid?)obj.GetValue(FullscreenElementIDProperty);
 132:  }
 133:  #endregion
 134:  
 135:  #region Initialization
 136:  
 137:  /// <summary>
 138:  /// Initializes the <see cref="ElementsFullScreenProvider"/> class.
 139:  /// </summary>
 140:  static ElementsFullScreenProvider()
 141:  {
 142:  PopupContentContainer = new Grid();
 143:  
 144:  PopupContainer = new Popup
 145:  {
 146:  Child = PopupContentContainer
 147:  };
 148:  
 149:  Application.Current.Host.Content.FullScreenChanged += delegate
 150:  {
 151:  if (_lastElementController == null) return;
 152:  if (!Application.Current.Host.Content.IsFullScreen)
 153:  {
 154:  ReturnElementFromFullScreen();
 155:  }
 156:  else
 157:  {
 158:  UpdateContentSize();
 159:  }
 160:  };
 161:  } 
 162:  #endregion
 163:  
 164:  #region Public Methods
 165:  
 166:  public static void BringElementToFullScreen(this UIElement element)
 167:  {
 168:  if (_lastElementController == null)
 169:  {
 170:  _lastElementController = new ElementController(element);
 171:  
 172:  _lastElementController.BringElementToFullScreen();
 173:  
 174:  PopupContentContainer.Children.Add(element);
 175:  PopupContainer.IsOpen = true;
 176:  }
 177:  }
 178:  
 179:  public static void ReturnElementFromFullScreen(this UIElement element)
 180:  {
 181:  ReturnElementFromFullScreen();
 182:  }
 183:  
 184:  public static void ReturnElementFromFullScreen()
 185:  {
 186:  if (_lastElementController != null)
 187:  {
 188:  PopupContentContainer.Children.Clear();
 189:  
 190:  _lastElementController.ReturnElementFromFullScreen();
 191:  
 192:  PopupContainer.IsOpen = false;
 193:  _lastElementController = null;
 194:  }
 195:  }
 196:  
 197:  public static void ToggleElementFullScreen(this UIElement element)
 198:  {
 199:  bool newValue = !Application.Current.Host.Content.IsFullScreen;
 200:  
 201:  bool toggle = false;
 202:  
 203:  if (newValue)
 204:  {
 205:  if (_lastElementController == null)
 206:  {
 207:  element.BringElementToFullScreen();
 208:  toggle = true;
 209:  }
 210:  }
 211:  else
 212:  {
 213:  if (_lastElementController != null && ReferenceEquals(element, _lastElementController.Element))
 214:  {
 215:  element.ReturnElementFromFullScreen();
 216:  toggle = true;
 217:  }
 218:  }
 219:  
 220:  if (toggle)
 221:  {
 222:  ToggleFullScreen();
 223:  }
 224:  }
 225:  
 226:  public static void ToggleFullScreen()
 227:  {
 228:  Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
 229:  }
 230:  
 231:  #endregion
 232:  
 233:  #region Private Method
 234:  
 235:  private static void UpdateContentSize()
 236:  {
 237:  if (Application.Current != null && Application.Current.Host != null && Application.Current.Host.Content != null)
 238:  {
 239:  double height = Application.Current.Host.Content.ActualHeight;
 240:  double width = Application.Current.Host.Content.ActualWidth;
 241:  
 242:  //if (Application.Current.Host.Settings.EnableAutoZoom)
 243:  //{
 244:  // double zoomFactor = Application.Current.Host.Content.ZoomFactor;
 245:  // if (zoomFactor != 0.0)
 246:  // {
 247:  // height /= zoomFactor;
 248:  // width /= zoomFactor;
 249:  // }
 250:  //}
 251:  
 252:  PopupContentContainer.Height = height;
 253:  PopupContentContainer.Width = width;
 254:  }
 255:  } 
 256:  #endregion
 257:  }
 258: }

 

调用的时候使用UIElement的扩展方法实现全屏:

 1: private void button1_Click(object sender, RoutedEventArgs e)
 2: {
 3:  SilverArea/*你希望全屏的元素*/.ToggleElementFullScreen();//调用UIElement的扩展方法
 4:  }

源码下载

2011-08-19 16h39_10

本文源码下载请点击此处。主要就一个类ElementsFullScreenProvider.cs,用起来就一个函数ToggleElementFullScreen(),简单之极。

作者: Mainz 发表于 2011-08-19 16:40 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"