WPF技巧 n问

问一:Popup控件Placement属性设置固定值后,在不同的电脑可能有不同行为的问题

Popup.Placement属性受SystemParameters.MenuDropAlignment(该值指示弹出菜单相对于相应菜单项是左对齐还是右对齐。)属性的影响,你可以这么设置:

if (SystemParameters.MenuDropAlignment)
{
	Popup.Placement = PlacementMode.Left;
}
else
{
	Popup.Placement = PlacementMode.Right;
}

问二:将ListBox的ItemsSource,Binding到List<String>为什么ListBox里面不是String列表而是ListBoxItem列表呢?

ItemsControl有两个虚方法:

protected override DependencyObject GetContainerForItemOverride()
{
      //return new CustomListItem();
}

protected override bool IsItemItsOwnContainerOverride(object item)
{
      //return item is CustomListItem;
}

顾名思义,这两个方法一个是判断有没有子项容器有没有被重写,一个是返回新的子项。你可以创建自己的ListBox,里面容纳自己的ListBoxItem,就像我上面那样(解掉两行注释)。

问三:如何以管理员身份启动应用程序?

在WPF项目添加应用程序清单文件app.manifest,找到如下所示的块:

<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC 清单选项
            如果要更改 Windows 用户帐户控制级别,请用以下节点之一替换
            requestedExecutionLevel 节点。

        <requestedExecutionLevel  level="requireAdministratorasInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            指定 requestedExecutionLevel 节点将会禁用文件和注册表虚拟化。
            如果要利用文件和注册表虚拟化实现向后
            兼容性,则删除 requestedExecutionLevel 节点。
        -->
        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
</requestedPrivileges>

将<requestedExecutionLevel level="asInvoker" uiAccess="false" />改为<requestedExecutionLevel level="requireAdministratorasInvoker" uiAccess="false" /> 即可,这里还有其他选项,不作赘述。

问四:应用程序启动后如何检查是否以管理员身份运行的?

		/// <summary>
		/// 检查是否是管理员身份
		/// </summary>
		private void CheckAdministrator()
		{
			var wi = WindowsIdentity.GetCurrent();
			var wp = new WindowsPrincipal(wi);

			bool runAsAdmin = wp.IsInRole(WindowsBuiltInRole.Administrator);

			if (!runAsAdmin)
			{
				// It is not possible to launch a ClickOnce app as administrator directly,
				// so instead we launch the app as administrator in a new process.
				var processInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().CodeBase);

				// The following properties run the new process as administrator
				processInfo.UseShellExecute = true;
				processInfo.Verb = "runas";

				// Start the new process
				try
				{
					Process.Start(processInfo);
				}
				catch (Exception ex)
				{
					logger.Info(ex);
				}

				// Shut down the current process
				Environment.Exit(0);
			}
		}

在App构造函数或者App.OnStartup方法中调用。

问五:WPF无边框阴影窗口

看到这个问题你一定是如下设置吧:

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350"
        AllowsTransparency="True"
        Background="Transparent"
        WindowStyle="None">
    <Grid Margin="10" Background="White">
        <Grid.Effect>
            <DropShadowEffect BlurRadius="10" ShadowDepth="0" />
        </Grid.Effect>
    </Grid>
</Window>

这样设置可以,但是窗体启动慢、性能低、不能拖动、不能拖改尺寸、不跟随系统窗口动画(最大化最小化时动态拉伸窗口)、没有窗体系统功能,另外你若这样设置窗口,窗口里面如果还有一个WebBrowser,那么这个WebBrowser不会显示。

WPF4.5新增了System.Windows.Shell命名空间,这个命名空间已经集成在了x:命名空间下,所以你现在可以这么创建窗口:

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Width="525"
        Height="350">
    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="30"
                      CornerRadius="0"
                      GlassFrameThickness="1"
                      NonClientFrameEdges="None"
                      ResizeBorderThickness="5"
                      UseAeroCaptionButtons="False" />
    </WindowChrome.WindowChrome>
    <Grid />
</Window>

关于WindowChrome类,查阅MSDN在线文档:WindowChrome

问六:WPF路由命令的可用状态不能及时刷新到UI控件的问题

路由命令的CanExecute事件并不是不停的“投石问路”的。路由命令处于性能考虑在窗体是激活状态的时候才会不停地“投石问路”,但有时候也是会出现不触发的情况,这个时候你需要点击一下窗体其他地方,触发一下焦点切换,才会再次执行CanExecute事件。如何避免这个问题,而让WPF始终不停地“投石问路”呢?

static ControlCommands()
{
         DispatcherTimer dt = new DispatcherTimer
         {
                Interval = TimeSpan.FromMilliseconds(500)
         };
         dt.Tick += (sender, e) =>
         {
		//强制 System.Windows.Input.CommandManager 引发 System.Windows.Input.CommandManager.RequerySuggested事件
                CommandManager.InvalidateRequerySuggested();
         };
         dt.Start();
}

使用Tick里面的代码强制路由命令执行CanExecute事件。

问七:属性的更改通知、集合的更改通知

属性的更改通知要实现INotifyPropertyChanged接口,如:

public class MyClass : INotifyPropertyChanged
{
	public event PropertyChangedEventHandler PropertyChanged;

	private void RaisePropertyChanged(string propertyname)
	{
		PropertyChangedEventHandler handle = this.PropertyChanged;
		if (!string.IsNullOrEmpty(propertyname) && handle != null)
		{
			handle.Invoke(this, new PropertyChangedEventArgs(propertyname));
		}
	}

	public string Property1
	{
		get { return this.Property1; }
		set
		{
			this.Property1 = value;
			this.RaisePropertyChanged("Property1");
		}
	}
}

这样Property1属性就具备了更改通知的功能(在WPFUI中绑定此属性时)。

集合的更改通知要实现INotifyCollectionChanged接口,WPF本身只提供了一个这样的接口就是System.Collections.ObjectModel.ObservableCollection<T>类,ItemsControl的ItemsSource属性绑定到该类时,对该类进行的添加等操作会及时的更新到UI上,而不实现INotifyCollectionChanged接口的类则会报“绑定的集合与源集合不一致”异常。

 

 

第一次写博,欢迎大家批评指正。

持续更新中…

时间: 2024-10-07 16:47:12

WPF技巧 n问的相关文章

WPF技巧-Canvas转为位图

转自:http://www.cnblogs.com/tmywu/archive/2010/09/14/1825650.html 在WPF中我们可以将Canvas当成一种画布,将Canvas中的控件当成元素,讲其转成位图文件: 如下效果 图1.1 你可以设置Canvas的宽度.高度和颜色类型,生成任何你想要的图片.实时呈现你设置的样式等效果. 包括创建一些特效如阴影等. WPF提供RenderTargetBitmap类将任何容器控件渲染成一个位图. 新建一个WPF项目,在页面中创建一个CANVAS

WPF 杂谈——开篇简言

这俩年多来笔者一直在从事关于WPF的开发.虽然不能说是专家级别的.但是对于WPF的应用还是有一定的了解.论他的灵活性决对不在WinForm之下.WPF的出现更是引发一段热议.他的何去何从更是让很多人感到迷茫.因为那个时候可以说只有Winow 7才能跟WPF完美的接合.可惜他出不逢时,XP占了大部分的市场.所以WPF的出生动静很大,可惜后力不足,渐渐的淡淡化他的光芒.于至于网络上更是有对WPF的死亡产生了很大的争议.但是这并没有让他沉默下去,这几年来window 8和window 10的推广更是让

[Aaronyang]谈谈2015年AY对WPF全面技术总结,AYUI来了

         原著:AY WPF博客- 把wpf推广出去,让那些鄙视的人说不 大家好! 我是AY,首先声明,我在做一件很枯燥的事情,我是个91后程序员,每天熬夜完成计划的过着下班后的生活. 那天有人反对,那天有人安慰,那天有人嘲讽,那天有人祝福. 过了6个月后,我对自己的梦想一直没有改变过,继续坚持,终于,AYUI诞生了. 今天有人说造轮子,今天有人说你好厉害,今天有人说开源吗? 有人说好喜欢... 有贬有褒,但是好的声音多了. 但是身体的各种问题也来了.. AY提供的WPF书籍下载: 下载

mediawiki中关于权限的问题

其实有个地方是我从来没有适应过得,那就是这样:以前在A,我是全权负责, 但是现在呢,我只是工作中的一环而已. 我只是mediawiki的管理员而已,我的工作成功与否是建立在别人的工作是否成功上的. 需求:customer想让一个组的人访问某个wiki的子页面. global的wiki是分为多个模块的,因此说:global的wiki是面向SONY整个公司的,面对不同的team的. 其中包括开发,Linux,Oracle,AD,dns分为多个模块. 所以说,不同的人有不同的访问页面. group在我

挨踢部落故事汇(16):技术人疲倦期的最佳实践

Coeus喜欢和朋友聊技术.怼产品.鄙销售.谈梦想.借着兴致与大家分享这几年遇到坑,经历的疲倦期和技术瓶颈,希望对大家有一定帮助. Coeus·新浪安徽站PHP主管 Coeus工作六年有余,一直从事PHP相关的Web开发工作.前端.服务器运维也做过,私活.技术顾问.个人规划的项目也接触做过.曾在小公司打过杂,也在外企熬过夜,目前在国内一家老牌互联网地方站做技术主管.这六年的工作期间Coeus踩过很多坑,做出了很多选择,很幸运的每一次都挺了过来.秘籍很简单:不能则学,不知则问,耻于问人,决无长进.

算法(插入、希尔、冒泡)

算法学习技巧 先问自己几个问题 什么是什么? 为什么要这么写? 稳定性? 时间复杂度? 冒泡排序 是什么:首先拿到第1个元素,和它第二个比较,较大的放右边:第二个与第三个比,一直重复下去 ,最后一个就是最大的数 为什么:总共有n个数,主要是控制轮数,第二个是控制次数.比的次数 为:n-1 稳定性 时间复杂度 方法一: def Bubble(arr): for i in range(len(arr)): for j in range(len(arr)-1-i): if arr[j]>arr[j+1

WPF 中的 Pack URI-访问程序集资源

在 Windows Presentation Foundation (WPF) 中,使用统一资源标识符 (URI) 标识和加载文件的方式有很多,包括: 指定当应用程序第一次启动时显示的用户界面 (UI). 加载图像. 导航到页 加载不可执行的数据文件. 在代码中使用 Pack URI 在代码中,可以通过实例化 Uri 类并将 pack URI 作为参数传递给构造函数来指定 pack URI.下面的示例说明了这一点. C# Uri uri = new Uri("pack://application

【转】WPF中的Binding技巧(二)

WPF中的Binding技巧(二)   接上篇, 我们来看一看Elementname,Source,RelativeSource 三种绑定的方式 1.ElementName顾名思义就是根据Ui元素的Name来进行绑定: 例子: <Window x:Name="MainWindow"> <Grid>               <Button Background="{Binding ElementName=MainWindow, Path=Bac

【转】WPF中Binding的技巧(一)

WPF中Binding的技巧(一) 在WPF应用的开发过程中Binding是一个非常重要的部分. 在实际开发过程中Binding的不同种写法达到的效果相同但事实是存在很大区别的. 这里将实际中碰到过的问题做下汇总记录和理解. 1. source = {binding} 和source = {binding RelativeSource={RelativeSource self},Path=DataContext}效果相同 理解:{binding} 不设定明确的绑定的source,这样bindin