日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference!

發布時間:2024/4/14 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:WPF 的 ElementName 在 ContextMenu 中無法綁定成功?試試使用 x:Reference!

版權聲明:本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名呂毅(包含鏈接:http://blog.csdn.net/wpwalter/),不得用于商業目的,基于本文修改后的作品務必以相同的許可發布。如有任何疑問,請與我聯系(walter.lv@qq.com)。 https://blog.csdn.net/WPwalter/article/details/83473313

在 Binding 中使用 ElementName 司空見慣,沒見它出過什么事兒。不過當你預見 ContextMenu,或者類似 Grid.Row / Grid.Column 這樣的屬性中設置的時候,ElementName 就不那么管用了。

本文將解決這個問題。


本文內容

      • 以下代碼是可以正常工作的
      • 以下代碼就無法正常工作了
      • 使用 x:Reference 代替 ElementName 能夠解決
        • 參考資料

以下代碼是可以正常工作的

<Window x:Class="Walterlv.Demo.BindingContext.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Name="WalterlvWindow" Title="Walterlv Binding Demo" Height="450" Width="800"><Grid Background="LightGray" Margin="1 1 1 0" MinHeight="40"><TextBlock><Run Text="{Binding Mode=OneWay}" FontSize="20" /><LineBreak /><Run Text="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /></TextBlock></Grid> </Window>

在代碼中,我們為一段文字中的一個部分綁定了主窗口的的一個屬性,于是我們使用 ElementName 來指定綁定源為 WalterlvWindow。


▲ 使用普通的 ElementName 綁定

以下代碼就無法正常工作了

保持以上代碼不變,我們現在新增一個 ContextMenu,然后在 ContextMenu 中使用一模一樣的綁定表達式:

<Window x:Class="Walterlv.Demo.BindingContext.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Name="WalterlvWindow" Title="Walterlv Binding Demo" Height="450" Width="800"><Grid Background="LightGray" Margin="1 1 1 0" MinHeight="40"><Grid.ContextMenu><ContextMenu><MenuItem Header="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /></ContextMenu></Grid.ContextMenu><TextBlock><Run Text="{Binding Mode=OneWay}" FontSize="20" /><LineBreak /><Run Text="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /></TextBlock></Grid> </Window>

注意,MenuItem 的 Header 屬性設置為和 Run 的 Text 屬性一模一樣的綁定字符串。不過運行之后的截圖顯示,右鍵菜單中并沒有如預期般出現綁定的字符串。

使用 x:Reference 代替 ElementName 能夠解決

以上綁定失敗的原因,是 Grid.ContextMenu 屬性中賦值的 ContextMenu 不在可視化樹中,而 ContextMenu 又不是一個默認建立 ScopeName 的控件,此時既沒有自己指定 NameScope,有沒有通過可視化樹尋找上層設置的 NameScope,所以在綁定上下文中是找不到 WalterlvWindow 的。如果調用去查找,得到的是 null。詳見:WPF 中的 NameScope。

類似的情況也發生在設置非可視化樹或邏輯樹的屬性時,典型的比如在 Grid.Row 或 Grid.Column 屬性上綁定時,ElementName 也是失效的。

此時最適合的情況是直接使用 x:Reference。

<Window x:Class="Walterlv.Demo.BindingContext.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Name="WalterlvWindow" Title="Walterlv Binding Demo" Height="450" Width="800"><Grid Background="LightGray" Margin="1 1 1 0" MinHeight="40"><Grid.ContextMenu><ContextMenu> - <MenuItem Header="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /> + <MenuItem Header="{Binding Source={x:Reference WalterlvWindow}, Path=DemoText, Mode=OneWay}" /></ContextMenu></Grid.ContextMenu><TextBlock><Run Text="{Binding Mode=OneWay}" FontSize="20" /><LineBreak /><Run Text="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /></TextBlock></Grid></Window>

不過,這是個假象,因為此代碼運行時會拋出異常:

XamlObjectWriterException: Cannot call MarkupExtension.ProvideValue because of a cyclical dependency. Properties inside a MarkupExtension cannot reference objects that reference the result of the MarkupExtension. The affected MarkupExtensions are:
‘System.Windows.Data.Binding’ Line number ‘8’ and line position ‘27’.

因為給 MenuItem 的 Header 屬性綁定賦值的時候,創建綁定表達式用到了 WalterlvWindow,但此時 WalterlvWindow 尚在構建(因為里面的 ContextMenu 是窗口的一部分),于是出現了循環依賴。而這是不允許的。

為了解決循環依賴問題,我們可以考慮將 x:Reference 放到資源中。因為資源是按需創建的,所以這不會造成循環依賴。

那么總得有一個對象來承載我們的綁定源。拿控件的 Tag 屬性也許是一個方案,不過專門為此建立一個綁定代理類也許是一個更符合語義的方法:

<Window x:Class="Walterlv.Demo.BindingContext.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="clr-namespace:Walterlv.Demo.BindingContext"x:Name="WalterlvWindow" Title="Walterlv Binding Demo" Height="450" Width="800"> + <Window.Resources> + <local:BindingProxy x:Key="WalterlvBindingProxy" Data="{x:Reference WalterlvWindow}" /> + </Window.Resources><Grid Background="LightGray" Margin="1 1 1 0" MinHeight="40"><Grid.ContextMenu><ContextMenu> - <MenuItem Header="{Binding Source={x:Reference WalterlvWindow}, Path=DemoText, Mode=OneWay}" /> + <MenuItem Header="{Binding Source={StaticResource WalterlvBindingProxy}, Path=Data.DemoText, Mode=OneWay}" /></ContextMenu></Grid.ContextMenu><TextBlock><Run Text="{Binding Mode=OneWay}" FontSize="20" /><LineBreak /><Run Text="{Binding ElementName=WalterlvWindow, Path=DemoText, Mode=OneWay}" /></TextBlock></Grid></Window>

至于 BindingProxy,非常簡單:

public sealed class BindingProxy : Freezable {public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new PropertyMetadata(default(object)));public object Data{get => (object) GetValue(DataProperty);set => SetValue(DataProperty, value);}protected override Freezable CreateInstanceCore() => new BindingProxy();public override string ToString() => Data is FrameworkElement fe? $"BindingProxy: {fe.Name}": $"Binding Proxy: {Data?.GetType().FullName}"; }

現在運行,右鍵菜單已經正常完成了綁定。


▲ 右鍵菜單已經正常完成了綁定


參考資料

  • c# - WPF databinding error in Tag property - Stack Overflow

總結

以上是生活随笔為你收集整理的WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 强乱中文字幕av一区乱码 | 亚洲精品一区二区三区新线路 | 亚洲一区二区精品在线观看 | 久久久久成人网 | 国产专区一 | 天堂精品视频 | 少妇高潮一区二区三区喷水 | 99爱爱 | 亚洲精品高清在线 | 一级国产精品 | 在线永久看片免费的视频 | 成人h动漫精品一区二区器材 | 欧美一级专区免费大片 | 国产精品美女久久久久久久 | 拍摄av现场失控高潮数次 | 日批网址 | 精品在线小视频 | 中文在线免费看视频 | 男插女动态图 | 秋霞影院午夜 | com国产| 日本成人在线免费视频 | 91色网站 | 性爱免费视频 | 一本久草 | 久久网国产 | 久久青青操 | 国产91精品高潮白浆喷水 | 欧美亚洲日本国产 | 香蕉人妻av久久久久天天 | 日韩欧美国产成人精品免费 | 黄片毛片在线看 | 东京热加勒比无码少妇 | 亚洲精品国产免费 | 国产999视频 | 强迫凌虐淫辱の牝奴在线观看 | 色图一区 | 日韩大片免费观看 | 亚洲精品国产精品乱码不99按摩 | 国产绿帽刺激高潮对白 | 翔田千里一区二区三区av | 一级片视频网站 | 国产91边播边对白在线 | 强伦轩人妻一区二区电影 | 美国av大片 | 国产人妻精品一区二区三 | 四虎av| 妇女一级片 | 国产福利免费视频 | 国产影视av | 韩国毛片视频 | 伦理片av| 国产片高清在线观看 | 人人亚洲| 亚洲一区二区三区电影在线观看 | 黄色网页在线观看 | 国产不卡视频在线观看 | 成人自拍一区 | 男人日女人在线观看 | 逼特逼在线视频 | 性高潮久久久久久久久久 | 冲田杏梨一区二区三区 | 人妻一区二区在线 | 日本熟女一区二区 | 欧美在线观看a | av不卡在线 | 国产成人精品视频 | 国产美女裸体无遮挡免费视频 | 永久黄网站 | 久久国产激情视频 | 自拍1页 | 久久精品国产清自在天天线 | 在线免费观看一级片 | 久色精品视频 | 超碰在线免费 | 桃色视频网站 | 久久噜噜色综合一区二区 | 欧美日韩国产一级片 | 奇米影视一区二区三区 | 精品国产视频在线 | 国产成人亚洲精品自产在线 | 黑丝美女一区二区 | 欧美精品欧美精品系列 | 快色视频在线观看 | 五月天丁香婷 | 黄色在线视频网站 | 日韩福利小视频 | 男人的天堂网av | 午夜在线成人 | 欧美 日韩 国产在线 | 福利视频99 | 成人精品免费网站 | 最新天堂在线视频 | 中文字幕一区二区三 | 韩国一区二区三区四区 | 亚洲av成人片色在线观看高潮 | 色黄网站在线观看 | 日本一区二区三区视频在线 | 成人资源在线观看 |