WPF屬性繫結測試(索引器方式)
小結:
如果屬性繫結路徑上的任何可通知變化屬性發生改變,其路徑及以下路徑都視為發生了變化,不管是否是可通知變化屬性,都會重新繫結新值。看來微軟對於繫結的機制是下了功夫的,如果採用簡單的反射,路徑尋找的方式,如果頁面元素比較多,層次比較多,效率肯定有問題的,看來有時間得反編譯,看看他們是如何搞的。下面是測試程式碼
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
<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>