小结:
如果属性绑定路径上的任何可通知变化属性发生改变,其路径及以下路径都视为发生了变化,不管是否是可通知变化属性,都会重新绑定新值。看来微软对于绑定的机制是下了功夫的,如果采用简单的反射,路径寻找的方式,如果页面元素比较多,层次比较多,效率肯定有问题的,看来有时间得反编译,看看他们是如何搞的。下面是测试代码
1)VVM
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace SilverlightApplication3
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.DataContext = new VMDDD();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
((VMDDD)(this.DataContext)).SetVisible2(false);
}
private void button7_Click(object sender, RoutedEventArgs e)
{
((VMDDD)(this.DataContext)).SetVisible(true);
}
}
public class VMDDD : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
Dictionary<string, CTRL> _Props = new Dictionary<string, CTRL>();
public Dictionary<string, CTRL> Props
{
get
{
return _Props;
}
set
{
_Props = value;
RaisePropertyChanged("Props");
}
}
public VMDDD()
{
_Props.Add("button1", new CTRL() { Name = "hello" });
}
public void SetVisible(bool visible)
{
//改变属性
this.Props["button1"].Name = "Albert";
this.Props["button1"].Visible = visible ? Visibility.Visible : Visibility.Collapsed;
}
public void SetVisible2(bool visible)
{
//改变更浅处属性
Dictionary<string, CTRL> theProps = new Dictionary<string, CTRL>();
theProps.Add("button1", new CTRL() { Name = "good"+new Random().Next(1,10000).ToString() });
theProps["button1"].Visible = visible ? Visibility.Visible : Visibility.Collapsed;
this.Props = theProps;
}
}
public class CTRL : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
private Visibility _Visible;
public Visibility Visible
{
get
{
return _Visible;
}
set
{
_Visible = value;
RaisePropertyChanged("Visible");
}
}
public string Name { get; set; }
}
}
2)xaml
<UserControl x:Class="SilverlightApplication3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<toolkit:DockPanel x:Name="LayoutRoot">
<Grid Height="40" Name="grid1" toolkit:DockPanel.Dock="Top" Visibility="{Binding Path=Props[button1].Visible,Mode=TwoWay}">
<Button Content="Button1" Height="23" HorizontalAlignment="Left" Margin="258,11,0,0" Name="button4" VerticalAlignment="Top" Width="75" />
</Grid>
<Grid Height="59" Name="grid2" toolkit:DockPanel.Dock="Top" >
<Button Content="Button2" Height="23" HorizontalAlignment="Left" Margin="250,8,0,0" Name="button3" VerticalAlignment="Top" Width="75" />
</Grid>
<Grid Height="66" Name="grid3" toolkit:DockPanel.Dock="Top" >
<Button Content="Button3" Height="23" HorizontalAlignment="Left" Margin="6,23,0,0" Name="button2" VerticalAlignment="Top" Width="75" />
</Grid>
<Grid Height="24" Name="grid4" toolkit:DockPanel.Dock="Top" VerticalAlignment="Center" UseLayoutRounding="False">
<Button Content="{Binding Path=Props[button1].Name,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="65,1,0,0" Name="button5" VerticalAlignment="Top" Width="75" />
</Grid>
<Grid Height="30" Name="grid5" toolkit:DockPanel.Dock="Bottom">
<Button Content="hide" Height="23" Name="button1" Width="75" Margin="127,0,197,6" Click="button1_Click" />
<Button Content="show" Height="23" Name="button7" Width="75" Margin="227,6,98,1" Click="button7_Click" />
</Grid>
<Button Content="Button5" Height="23" Name="button6" Width="75" />
</toolkit:DockPanel>
</UserControl>