【WPF】对Frame控件的Content属性做绑定时出现的一个小问题
修改:经过研究,发现只要在Frame上设置JournalEntry.KeepAlive="True"就可以使用第一种绑定到Source的最简单的办法来实现文中的效果。不用自己管理Page
这几天给给别人做了几个Demo,但觉得每个Demo都做一个工程太麻烦,不好管理,于是决定把每个Demo都各自用Page,然后通过一个列表,可以选择各个页面来查看。就如下图的效果:
当从左边选中一项后,右边的Frame会展示相应的内容。
我采用了一个xml文件来描述相关的信息,示例如下:
<Pages>
<Page Name="Page1" Uri="/FrameContent;Component/Page1.xaml"/>
<Page Name="Page2" Uri="/FrameContent;Component/Page2.xaml"/>
</Pages>
这是一个非常简单的描述,每个Page项描述这个Page的Name和对应的xaml文件,然后我们可以简单用下面的方式来绑定这些信息来达到目的:
ItemsSource="{Binding Source={StaticResource ListSource}}"
DisplayMemberPath="@Name"/>
<!-- 最简单的方式就是用Frame的Source来做绑定,不过这样会导致每次都生成新的实例 -->
<Frame DataContext="{Binding ElementName=ListBox1, Path=SelectedItem}"
Source="{Binding XPath=@Uri}"/>
不过,这样有一个小小的问题在于,每次我切换Page的时候,都将重新生成一个Page的实例,以前在Page上做的一些操作会消失。这不是我想要的,我希望有一个类似于PagePool的东西来缓存我这些创建好的页面,这样在切换的时候会减少创建实例的开销,同时可以保证无论怎么切换始终是同一个Page的实例。于是我做了如下的更改:
ItemsSource="{Binding Source={StaticResource ListSource}}"
DisplayMemberPath="@Name"/>
<Frame x:Name="PageHost1"
NavigationUIVisibility="Hidden"
Content="{Binding ElementName=ListBox1, Path=SelectedItem, Converter={StaticResource Converter}}"/>
我直接把Frame的Content属性绑定到选中的项上,并且用一个Converter来返回Page的实例,在Converter里面,我用一个Dictionary来保存创建过的页面,保证它们只会被创建一次:
{
// 使用Page池来减少创建Page的开销
private Dictionary<string, Page> _pagePool = new Dictionary<string, Page>();
IValueConverter Members#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// 把Frame的Content绑定到ListBox的SelectedItem上,无法对变化做出响应
XmlElement node = value as XmlElement;
if (node != null)
{
string name = node.Attributes["Name"].Value;
string uri = node.Attributes["Uri"].Value;
if (this._pagePool.ContainsKey(name))
{
return this._pagePool[name];
}
else
{
Page page = Application.LoadComponent(new Uri(uri, UriKind.Relative)) as Page;
this._pagePool.Add(name, page);
return page;
}
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
XmlElement node = value as XmlElement;
if (node != null)
{
string name = node.Attributes["Name"].Value;
string uri = node.Attributes["Uri"].Value;
if (this._pagePool.ContainsKey(name))
{
return this._pagePool[name];
}
else
{
Page page = Application.LoadComponent(new Uri(uri, UriKind.Relative)) as Page;
this._pagePool.Add(name, page);
return page;
}
}
return null;
}
#endregion
}
理论上来说,这应该工作良好,然而,实际上却发生一点小小的意外:
Frame展示的内容只跟第一次选中的项有关,其后无论如何切换,Frame的内容均不受影响
难道是Frame的Content属性默认是以OneTime的模式来绑定的?于是我显示地指定Mode=OneWay,结果依然如此。
莫非Frame的Content属性只能指定一次?好吧,既然正着来不行,那我就试试反着的。
索性,我把ListBox的SeletedItem使用OneWayToSource的模式绑定到Frame的Content属性上。当然,这种情况下,FrameContentConverter里面的ConvertBack方法需要实现。
ItemsSource="{Binding Source={StaticResource ListSource}}"
DisplayMemberPath="@Name"
SelectedItem="{Binding ElementName=PageHost2, Path=Content, Converter={StaticResource Converter}, Mode=OneWayToSource}"/>
<Frame x:Name="PageHost2" NavigationUIVisibility="Hidden"/>
采用这种方式后,一切正常了:
这说明,Frame的Content属性不是只能设置一次的,只是在对Frame的Content属性做绑定时,由于某种未知的原因,无法对数据源的变化产生响应,鉴于我目前的系统是Vista SP1,上次的Frame出现了渲染上的问题,这次我也没有找没装SP1的机子做测试,所以我并不能确定这是WPF本身的BUG还是sp1引起的问题,还是我某个地方没有弄好造成的。
做了一个对比的示例,有兴趣的读者可以下载回去看看。http://files.cnblogs.com/RMay/FrameContent.rar
转载于:https://www.cnblogs.com/RMay/archive/2008/07/28/1254383.html
【WPF】对Frame控件的Content属性做绑定时出现的一个小问题相关推荐
- WPF对某控件添加右键属性
代码创建右键属性 ContextMenu cm = new ContextMenu();MenuItem mi = new MenuItem();mi.Header = "打开此文件所有文件 ...
- WPF中DataGrid控件
WPF中DataGrid控件的个别属性使用 //设置不可自动拉伸宽度dataGrid.CanUserResizeColumns = false;//第一列不可见dataGrid.HeadersVisi ...
- 如何 修改服务器控件的text,设置TextBox控件的TextMode属性
我想在程式代碼中將TextBox控件的TextMode属性设置為Password,寫成TextBox1.TextMode=MultiLine和TextBox1.TextMode="Multi ...
- C#控件及常用属性整理
C#控件一览表 前所未有的震撼(太详细了) 1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体. (2) WindowState属性: 用来 ...
- 2021-08-11 WPF控件专题 Frame 控件详解
1.Frame 控件介绍 Frame ContentControl 支持导航,可以将一个页面导航到另一个页面. 可能承载Page页, TabItem ContentControl 直接在内部添加元素, ...
- WPF中通过控件Margin属性设置控件位置
WPF中通过控件Margin属性设置控件位置 一.Margin属性简介 二.Margin在cs文件中定义 三.Margin设置控件位置 四.参考文档 一.Margin属性简介 在使用WPF进行页面设计 ...
- MVVMLight 实现指定Frame控件的导航
MVVMLight 实现指定Frame控件的导航 原文:MVVMLight 实现指定Frame控件的导航 在UWP开发中,利用汉堡菜单实现导航是常见的方法.汉堡菜单导航一般都需要新建一个Frame控件 ...
- 潜移默化学会WPF(难点控件treeview)--改造TreeView(CheckBox多选择版本),递归绑定数据...
目前自己对treeview的感慨很多 今天先讲 面对这种 表结构的数据 的其中一种绑定方法,后面多几列其他属性都没关系,例如多个字段, 1 A 0 2 B 0 3 C 0 4 D 1 ...
- WPF Calendar 日历控件 样式自定义
原文:WPF Calendar 日历控件 样式自定义 粗略的在代码上做了些注释 blend 生成出来的模版 有的时候 会生成 跟 vs ui界面不兼容的代码 会导致可视化设计界面 报错崩溃掉 但是确不 ...
- 转 8天入门wpf—— 第六天 细说控件
WPF中的控件大体上分为四类 内容控件 ContentControl直接从Control类中派生出来,内容控件的最大特征是含有一个Content属性,Content属性的类型是Object,因此内容控 ...
最新文章
- oracle 表空间初始分配,在Oracle中创建用户时,若未提及DEFAULT TABLESPACE关键字,则Oracle就将哪个表空间分配给用户作为默认表空间。...
- Xamarin Essentials教程使用加速度传感器Accelerometer
- sprintboot-learn(一)
- 1362. 健康的荷斯坦奶牛【难度: 一般 / 二进制枚举】
- 邀您参与 | 阿里巴巴如何扩展 K8s 调度器支持 AI 和大数据任务?
- Kittle工具抽取文件出现乱码的情况解决方法
- POJ3678-Katu Puzzle【2-SAT】
- java property_property在Java中的用法
- 面试题 35 : 复杂链表的复制
- Chrome development tools学习笔记(3)
- 如何掌握mysql的查询语句_如何分析mysql的查询语句
- 阿里云云计算 15 在线实验--OSS的使用
- UVC系列2-探索Android UVC协议
- 硬刚Hive | 4万字基础调优面试小总结
- linux 使用icc运行tcl,Tcl在ICC2中的应用:定义一个proc,实现将一个cell直接替换成另一个功能不等价的cell...
- R语言潜在变量模型、探索性因子分析EFA、验证性因素分析(CFA)、结构方程建模(SEM)之间的关系、潜在变量模型常用包:ltm包、sem包、OpenMx包、Lavaan包、lsa包、ca包等
- 高项考试-信息化知识
- 利率浮动值60BP什么意思,利率上浮50bp是什么意思
- IIS Express 7.5 directory browsing 启用目录浏览
- matlab计算后验概率,基于深度神经网络后验概率算法的口语发音评测方法与流程...