<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      享受代碼,享受人生

      SOA is an integration solution. SOA is message oriented first.
      The Key character of SOA is loosely coupled. SOA is enriched
      by creating composite apps.
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      How does ElementName Binding work – Part 3 InheritanceContext

      Posted on 2010-06-12 15:19  idior  閱讀(2270)  評論(1)    收藏  舉報

      In this part, I am going to introduce a new concept called InheritanceContext. In WPF, there are some elements are not FrameworkElement or even Visual, which means they will not be shown on either Logical Tree or Visual Tree, e.g. Brush, however we still wish they can enjoy the feature called “property value inheritance”. Property value inheritance enables child elements to obtain the value of a particular property from parent elements, inheriting that value as it was set anywhere in the nearest parent element.  

      In following example, the Brush can get the DataContext property from its parent, however a Brush is neither a FramewrokElement nor Visual.

       

      <Window x:Class="TestElementBindingInUserControl.MainWindow">
          <StackPanel DataContext="Red">
              <Rectangle Width="75" Height="75">
                  <Rectangle.Fill>
                      <SolidColorBrush Color="{Binding}" />
                  </Rectangle.Fill>
              </Rectangle>
          </StackPanel>
      
      </Window> 

       

      In this example, Brush doesn’t have a logical parent nor visual parent, so how does it get the DataContext property from its parent? The secret is in InheritanceContext. Brush is a Freezable object whose InheritanceContext property is set to the element which contains it.

      Here is the Rectangle, while Rectangle inherits the DataContext property from its Logical Parent StatckPanel.

      With the help of InheritanceContext, the ElementName Binding will work properly in following codes:

       
      <Window x:Class="TestElementBindingInUserControl.MainWindow">
          <StackPanel>
              <Button Content="Blue" x:Name="btn"/>
              <Rectangle Width="75" Height="75">
                  <Rectangle.Fill>
                      <SolidColorBrush Color="{Binding ElementName=btn, Path=Content}" />
                  </Rectangle.Fill>
              </Rectangle>
          </StackPanel>
      </Window> 

      Although SolidColorBrush doesn’t have a Logical parent, it will try to get its InheritanceContext instead, by which it will reach the Rectangle, then follow by the logical parent, we will find the Window which owns a NameScope; Finally btn will be found in this NameScope.

      Now let’s take a look at a popular issue in WPF development: use ElementName in ToolTip or ContextMenu.

       

      <Window x:Class="TestElementBindingInUserControl.MainWindow"
              Title="MainWindow" x:Name="win">
          <Button >
              <Button.ToolTip>
                  <TextBox x:Name="tbx" Text="{Binding ElementName=win, Path=Title}"/>
              </Button.ToolTip>
          </Button>
      </Window> 

      The content defined in the a ToolTip is not part of Logical tree or Visual tree, it’s not a Freezable object either. Then how can we use ElementName binding in the content?

       

      A straightforward solution comes into my mind is to do some hack to set the InheritanceContext property of TextBox to the Window directly. By looking into the source code of FrameworkElement, I found a static filed called InheritanceContextField whose type is UncommonField<DependencyObject> in which there is a SetValue method. By knowing this, I can use reflection to set the InheritanceContext manually.

            void Window_Loaded(object sender, RoutedEventArgs e)
              {
       
                  var tooltipContent = tbx.tooltip;
       
                  var field = typeof(FrameworkElement).GetField("InheritanceContextField",
                                                                BindingFlags.static | BindingFlags.nonpublic);
       
                  var inheritanceContext=field.GetValue(null);
       
                  //type of UncommonField<DependencyObject>
                  var type = Type.GetType("System.Windows.UncommonField`1[
                                                                          [System.Windows.Dependencyobject,
                                                                           windowsbase,
                                                                           version=3.0.0.0,
                                                                           culture=neutral,
                                                                           publickeytoken=31bf3856ad364e35]
                                                                        ],
                                          windowsbase, version=3.0.0.0, culture=neutral, publickeytoken=31bf3856ad364e35"
      );
       
        
       
                  var setMethod=type.GetMethod("SetValue");
                  setMethod.Invoke(inheritanceContext,new object[]{ tooltipContent,this});
              }


      Although it’s not a good fix, it do resolve the problem. Do we have a better solution? Since ElementName binding cannot work here, we can try to use another Binding - Source Binding.

       

      First of all, we need to define a Spy make it inherit from Freezable class,

      public class ElementSpy : Freezable
         {
           
             public static readonly DependencyProperty ValueProperty =
                 DependencyProperty.Register("Value", typeof(object), typeof(ElementSpy),
                     new FrameworkPropertyMetadata(null));
         
             public object Value
             {
                 get { return (object)GetValue(ValueProperty); }
                 set { SetValue(ValueProperty, value); }
             }
      
             protected override Freezable CreateInstanceCore()
             {
                 throw new NotImplementedException();
             }
         }
       

      Then we put it into the Resource of the Window. Since Freezable object’s InheritanceContext will be set to the containing element, here it’s the window, Element binding will work fine for ElementSpy.

      <Window x:Class="TestElementBindingInUserControl.MainWindow"
              Title="MainWindow" x:Name="win">
      
          <Window.Resources>
              <local:ElementSpy x:Key="spy" Value="{Binding ElementName=win, Path=Title}"/>
          </Window.Resources>
      </Window> 
       

      Now we can simply use ElementSpy as a bridge to make ElementName Binding work for ToolTip.

       

      <Window x:Class="TestElementBindingInUserControl.MainWindow"
              Title="MainWindow" x:Name="win">
      
          <Window.Resources>
              <local:ElementSpy x:Key="spy" Value="{Binding ElementName=win, Path=Title}"/>
          </Window.Resources>
          <Button >
              <Button.ToolTip>
                  <TextBox  Text="{Binding Source={StaticResource spy}, Path=Value}"/>
              </Button.ToolTip>
          </Button>
      </Window> 

       

      Here is the rule how ElementName binding works: 

      1. Get the BindingExpression which is created by the ElementName Binding.
      2. Start from the TargetElement of the BindingExpression. If the value of BindingExpression’s ResolveNamesInTemplate property is true, it will search in the TargetElement’s template, if an element with the same name can be found in its template then return it, else go to next step.
      3. Keep searching on the logic tree via its logic parent or InheritanceContext(when logic parent is null), until an element which has NameScope is found, let’s call it NameScopeElement. If no element owns a NameScope, search will stop.
      4. Call the NameScope.FindName method on the found NameScope.
      5. If the element is found, return it, otherwise try to get the template parent of NameScopeElement; if the template parent is null, it will stop search. or it goes back to step 3, search on the logic tree for an element owns a NameScope.

       

      Related resources:

      Enable ElementName Bindings with ElementSpy

      Artificial Inheritance Contexts in WPF

      Hillberg Freezable Trick

      Leveraging Freezables to Provide an Inheritance Context for Bindings

      主站蜘蛛池模板: 国产绿帽在线视频看| 精品无码国产污污污免费| 亚洲日本欧洲二区精品| 狠狠干| 99久久免费只有精品国产| 日韩精品区一区二区三vr| 亚洲第一二三区日韩国产| 国产精品自拍一二三四区| 一本精品99久久精品77| 亚洲青青草视频在线播放| 色狠狠色噜噜AV一区| 国产主播精品福利午夜二区| 国产乱弄免费视频观看| 麻豆国产成人AV在线播放| 亚洲av噜噜一区二区| 日韩大片高清播放器| 亚洲一区二区三区小蜜桃| 日本阿v片在线播放免费| 岐山县| 人人澡人人透人人爽| 亚洲VA欧美VA国产综合| 午夜成人性爽爽免费视频| 欧美色欧美亚洲高清在线视频 | 亚洲av无码牛牛影视在线二区| 蜜臀av日韩精品一区二区| 久久精品国产久精国产果冻传媒 | 国产女高清在线看免费观看| 在线国产精品中文字幕| 久久久久99精品成人片| 在线亚洲午夜片av大片| 华人在线亚洲欧美精品| 通辽市| 九色综合久99久久精品| 天堂a无码a无线孕交| 香蕉久久夜色精品国产成人| 日韩亚洲精品中文字幕| 铜鼓县| 久久人人97超碰精品| 国产极品美女高潮无套| 另类专区一区二区三区| 高清偷拍一区二区三区|