Wpf自定义inkcanvas绑定 [英] Wpf custom inkcanvas binding
问题描述
我正在尝试将儿童收藏绑定到自定义Inkcanvas。在这一刻,程序从画布到代码绑定没有问题,但没有问题。
谢谢你的帮助
Petr
调试日志:
线程0x2c88已退出,代码为259(0x103)。
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\Users\petr.ehler \Documents\Visual Studio 2013 \Projects\test_wpf \test_wpf\bin\Debug\test_wpf.exe。符号已加载。
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ microsoft.Net \assembly \ GAC_MSIL \ System.Configuration \v4 .0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll。符号已加载。
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \assembly \ GAC_MSIL \ PresentationFramework.Aero \v4 .0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll。符号已加载。
System.Windows.Data警告:56:为绑定创建BindingExpression(hash = 22226817)(hash = 54181020)
System.Windows.Data警告:58:路径:'BorderItems'
系统.Windows.Data警告:61:BindingExpression(hash = 22226817):默认更新触发器已解析为PropertyChanged
System.Windows.Data警告:62:BindingExpression(hash = 22226817):附加到test_wpf.MyCanvas.Source(hash = 46367191)
System.Windows.Data警告:67:BindingExpression(hash = 22226817):解析源
System.Windows.Data警告:70:BindingExpression(hash = 22226817):找到数据上下文元素: MyCanvas(hash = 46367191)(OK)
System.Windows.Data警告:71:BindingExpression(hash = 22226817):DataContext为null
System.Windows.Data警告:65:BindingExpression(hash = 22226817 ):解析源延迟
System.Windows.Data警告:67:BindingExpression(hash = 22226817):解析源
System.Windows.Data警告:70:BindingExpression(hash = 22226) 817):找到数据上下文元素:MyCanvas(hash = 46367191)(OK)
System.Windows.Data警告:78:BindingExpression(hash = 22226817):激活根项目MainWindow(hash = 3528959)
System.Windows.Data警告:108:BindingExpression(hash = 22226817):在0级 - 对于MainWindow.BorderItems找到存取器RuntimePropertyInfo(BorderItems)
System.Windows.Data警告:104:BindingExpression(hash = 22226817) :使用访问者RuntimePropertyInfo(BorderItems)替换级别0的项目(哈希= 3528959)
System.Windows.Data警告:101:BindingExpression(哈希= 22226817):来自MainWindow的级别0的GetValue(哈希= 3528959) )使用RuntimePropertyInfo(BorderItems):ObservableCollection`1(hash = 55866471 Count = 0)
System.Windows.Data警告:80:BindingExpression(hash = 22226817):TransferValue - 得到原始值ObservableCollection`1(hash = 55866471) Count = 0)
System.Windows.Data警告:89:BindingExpression(hash = 22226817):TransferValue - 使用final va lue ObservableCollection`1(hash = 55866471 Count = 0)
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \ assembly\GAC_MSIL\PresentationFramework-SystemXmlLinq\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXmlLinq.dll。符号已加载。
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \assembly \ GAC_MSIL \ PresentationFramework-SystemXml \v4 .0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXml.dll。符号已加载。
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ Microsoft \\ net\assembly \ GAC_MSIL \ UIAutomationTypes \v4.0_4 .0.0.0__31bf3856ad364e35\UIAutomationTypes.dll。符号已加载。
System.Windows.Data警告:95:BindingExpression(hash = 22226817):从MainWindow获得PropertyChanged事件(hash = 3528959)
System.Windows.Data警告:101:BindingExpression(hash = 22226817):使用RuntimePropertyInfo(BorderItems)从MainWindow(hash = 3528959)获取0级GetValue:ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:80:BindingExpression(hash = 22226817):TransferValue - 得到原始值ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:89:BindingExpression(hash = 22226817):TransferValue - 使用最终值ObservableCollection`1(hash = 55866471 Count = 1)
'test_wpf.vshost.exe'(CLR v4.0.30319:test_wpf.vshost.exe):已加载'C:\ Windows \ Microsoft.Net \assembly\GAC_MSIL \ PresentationFramework-SystemData \v4 .0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemData.dll。符号已加载。
System.Windows.Data警告:95:BindingExpression(hash = 22226817):从MainWindow获得PropertyChanged事件(hash = 3528959)
System.Windows.Data警告:101:BindingExpression(hash = 22226817):使用RuntimePropertyInfo(BorderItems)从MainWindow(hash = 3528959)获取0级GetValue:ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:80:BindingExpression(hash = 22226817):TransferValue - 得到原始值ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:89:BindingExpression(hash = 22226817):TransferValue - 使用最终值ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:95:BindingExpression(hash = 22226817):从MainWindow获得PropertyChanged事件(hash = 3528959)
System.Windows.Data警告:101:BindingExpression(hash = 22226817):使用RuntimePropertyInfo(BorderItems)从MainWindow(hash = 3528959)获取0级GetValue:ObservableCollection`1(hash = 55866471 Count = 1)
S ystem.Windows.Data警告:80:BindingExpression(hash = 22226817):TransferValue - 得到原始值ObservableCollection`1(hash = 55866471 Count = 1)
System.Windows.Data警告:89:BindingExpression(hash = 22226817 ):TransferValue - 使用最终值ObservableCollection`1(hash = 55866471 Count = 1)
线程0x3784已退出,代码为259(0x103)。
线程0x3050已退出,代码为259(0x103)。
程序'[12308] test_wpf.vshost.exe'退出时代码为0(0x0)。
我尝试过:
主类
<前lang =c# > 使用系统;
使用 System.Collections.Generic;
使用 System.Collections.ObjectModel;
使用 System.Collections.Specialized;
使用 System.ComponentModel;
使用 System.Windows;
使用 System.Windows.Input;
命名空间 test_wpf
{
public partial class MainWindow:Window,INotifyPropertyChanged
{
public ObservableCollection< ItemDetail> BorderItems
{
get ;
set ;
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
DataContext = this ;
BorderItems = new ObservableCollection< ItemDetail>();
}
private void Button_Click( object sender,RoutedEventArgs e)
{
if (BorderItems.Count == 0 )
{
return ;
}
BorderItems [ 0 ]。X = 200 ;
BorderItems [ 0 ]。Y = 300 ;
BorderItems [ 0 ]。宽度= 200 ;
BorderItems [ 0 ]。高度= 100 ;
if (PropertyChanged!= null )
PropertyChanged(< span class =code-keyword> this , new PropertyChangedEventArgs( BorderItems跨度>));
}
私有 void Button_Click_1( object sender,RoutedEventArgs e)
{
ItemDetail d = new ItemDetail();
d.X = 100 ;
d.Y = 100 ;
d.Width = 100 ;
d.Height = 100 ;
d.Type = text;
d.Text = 测试 + BorderItems.Count.ToString();
BorderItems.Add(d);
if (PropertyChanged!= null )
PropertyChanged(< span class =code-keyword> this , new PropertyChangedEventArgs( BorderItems跨度>));
}
}
}
MyCanvas
使用系统;
使用 System.Collections.Generic;
使用 System.Collections.ObjectModel;
使用 System.Collections.Specialized;
使用 System.Linq;
使用 System.Text;
使用 System.Threading.Tasks;
使用 System.Windows;
使用 System.Windows.Controls;
使用 System.Windows.Data;
使用 System.Windows.Media;
命名空间 test_wpf
{
public class MyCanvas:InkCanvas
{
// 只是一个简单的INotifyCollectionChanged集合
public ObservableCollection< ItemDetail>来源{获取; set ; }
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register( Source,
typeof (ObservableCollection< ItemDetail>),
typeof (MyCanvas),
new FrameworkPropertyMetadata( new ObservableCollection< ItemDetail>(),
new PropertyChangedCallback(SourceChanged)));
// 在设置新值时调用(例如通过绑定)
受保护 静态 void SourceChanged(DependencyObject sender,DependencyPropertyChangedEventArgs args)
{
// 获取更改本地值
var instance = sender as MyCanvas;
// 将要设置的新集合
ObservableCollection< ItemDetail> newCollection = args.NewValue as ObservableCollection< ItemDetail> ;;
// 已设置的上一个集合
ObservableCollection< ItemDetail> oldCollection = args.OldValue as ObservableCollection< ItemDetail> ;;
if (oldCollection!= null )
{
// 从旧集合中删除CollectionChangedEventHandler
oldCollection.CollectionChanged - = new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);
}
// 清除集合中所有以前的子项
instance.Children.Clear();
if (newCollection!= null )
{
// 添加新集合的所有子项
foreach (ItemDetail item in newCollection)
{
AddControl(item,instance);
}
// 将新的CollectionChangedEventHandler添加到新集合
newCollection.CollectionChanged + = new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);
}
}
// 在集合中的项目发生更改时附加
protected void collection_CollectionChanged( object sender,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// 在子集合中添加新项目
foreach (ItemDetail项目 e.NewItems)
{
AddControl(item);
}
}
受保护 静态 void AddControl(ItemDetail item,InkCanvas parentControl)
{
Border border = new Border();
border.DataContext = item;
border.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString( #000000\" 跨度>));
border.Width = item.Width;
border.Height = item.Height;
if (item.Type == text)
{
TextBlock tb = new TextBlock();
tb.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString( #FFFFFF跨度>));
tb.FontSize = 25 ;
tb.HorizontalAlignment = HorizontalAlignment.Center;
tb.VerticalAlignment = VerticalAlignment.Center;
绑定TextBinding = new 绑定( Text 跨度>);
TextBinding.Source = item;
TextBinding.Mode = BindingMode.TwoWay;
tb.SetBinding(TextBlock.TextProperty,TextBinding);
// tb.Text = item.Text;
border.Child = tb;
}
parentControl.Children.Add(border);
Binding XBinding = new Binding( X跨度>);
XBinding.Source = item;
XBinding.Mode = BindingMode.TwoWay;
绑定YBinding = new 绑定( Y跨度>);
YBinding.Source = item;
YBinding.Mode = BindingMode.TwoWay;
border.SizeChanged + = border_SizeChanged;
border.SetBinding(InkCanvas.LeftProperty,XBinding);
border.SetBinding(InkCanvas.TopProperty,YBinding);
}
private static void border_SizeChanged( object sender,SizeChangedEventArgs e)
{
Border border = sender as 边框;
if (border == null )
{
throw new ArgumentException( 意外的对象。预期的边界);
}
var i = border.DataContext;
ItemDetail itemDetail = i as ItemDetail;
if (itemDetail == null )
{
throw new ArgumentException( 意外的对象。预期的ItemDetail);
}
itemDetail.Width = border.ActualWidth;
itemDetail.Height = border.ActualHeight;
}
受保护 void AddControl(ItemDetail item)
{
AddControl(item, this );
}
静态 MyCanvas()
{
DefaultStyleKeyProperty.OverrideMetadata( typeof (MyCanvas), new FrameworkPropertyMetadata( typeof ( MyCanvas)));
}
public MyCanvas()
: base ()
{
}
}
}
项目明细
使用系统;
使用 System.Collections.Generic;
使用 System.ComponentModel;
使用 System.Linq;
使用 System.Text;
使用 System.Windows.Controls;
命名空间 test_wpf
{
public class ItemDetail:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int X {获得跨度>; set ; }
public int Y { get 跨度>; set ; }
public double 宽度{ get 跨度>; set ; }
public double 高度{ get 跨度>; set ; }
public string 输入{ get 跨度>; set ; }
public string 文字{ get 跨度>; set ; }
}
}
MainClassWPF
< 窗口 x:Class = test_wpf.MainWindow
垂直 >
xmlns = http://schemas.microsoft.com/winfx/2006 / xaml / presentation
xmlns:x = http://schemas.microsoft.com/winfx/ 2006 / xaml
xmlns:src = clr-namespace:test_wpf
标题 = InkCanvasElementSelection
ResizeMode = CanResize
xmlns:ComponentModel = clr-namespace:System.ComponentModel; assembly = WindowsBase
高度 < span class =code-keyword> = 800 宽度 = 600 >
< DockPanel LastChildFill = True >
< span class =code-keyword>< StackPanel DockPanel.Dock = 左 宽度 = 200 方向 =
< 行 保证金 = 5 / >
< TextBlock > 创建新元素< / TextBlock >
< 按钮 点击 = Button_Click_1 高度 = 20 内容 = 新 / >
< 行 保证金 = 5 / >
< TextBlock > 更改元素0 < / TextBlock >
< / StackPanel >
< src:MyCanvas 来源 = {Binding Path = BorderItems,Mode = TwoWay} 背景 < span class =code-keyword> = AliceBlue EditingMode = 选择 / >
< / DockPanel >
< / Window >
解决方案非常简单。 Inkcanvas不知道ItemDetail类的变化。 ItemDetail类无法观察到。只需更新类如
public class ItemDetail:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged( String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if ( null != handler)
{
handler( this , new PropertyChangedEventArgs(propertyName));
}
}
private int _x;
private int _y;
private double _width;
private double _height;
private string _type;
private string _text;
public int X {
get { return _x; }
set {_ x = value ; NotifyPropertyChanged(\"X\"); }
}
public int Y
{
get { return _y; }
set { _y = value; NotifyPropertyChanged(\"Y\"); }
}
public double Width
{
get { return _width; }
set { _width = value; NotifyPropertyChanged(\"Width\"); }
}
public double Height
{
get { return _height; }
set { _height = value; NotifyPropertyChanged(\"Height\"); }
}
public string Type
{
get { return _type; }
set { _type = value; NotifyPropertyChanged(\"Type\"); }
}
public string Text
{
get { return _text; }
set { _text = value; NotifyPropertyChanged(\"Text\"); }
}
}
and the code is functional.
Petr
Hi,
I am trying to Bind Children collection to Custom Inkcanvas. In this moment program binds from canvas to code without problem, but not othreside.
Thank you for help
Petr
Debug Log:
The thread 0x2c88 has exited with code 259 (0x103). 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Users\petr.ehler\Documents\Visual Studio 2013\Projects\test_wpf\test_wpf\bin\Debug\test_wpf.exe'. Symbols loaded. 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll'. Symbols loaded. 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll'. Symbols loaded. System.Windows.Data Warning: 56 : Created BindingExpression (hash=22226817) for Binding (hash=54181020) System.Windows.Data Warning: 58 : Path: 'BorderItems' System.Windows.Data Warning: 61 : BindingExpression (hash=22226817): Default update trigger resolved to PropertyChanged System.Windows.Data Warning: 62 : BindingExpression (hash=22226817): Attach to test_wpf.MyCanvas.Source (hash=46367191) System.Windows.Data Warning: 67 : BindingExpression (hash=22226817): Resolving source System.Windows.Data Warning: 70 : BindingExpression (hash=22226817): Found data context element: MyCanvas (hash=46367191) (OK) System.Windows.Data Warning: 71 : BindingExpression (hash=22226817): DataContext is null System.Windows.Data Warning: 65 : BindingExpression (hash=22226817): Resolve source deferred System.Windows.Data Warning: 67 : BindingExpression (hash=22226817): Resolving source System.Windows.Data Warning: 70 : BindingExpression (hash=22226817): Found data context element: MyCanvas (hash=46367191) (OK) System.Windows.Data Warning: 78 : BindingExpression (hash=22226817): Activate with root item MainWindow (hash=3528959) System.Windows.Data Warning: 108 : BindingExpression (hash=22226817): At level 0 - for MainWindow.BorderItems found accessor RuntimePropertyInfo(BorderItems) System.Windows.Data Warning: 104 : BindingExpression (hash=22226817): Replace item at level 0 with MainWindow (hash=3528959), using accessor RuntimePropertyInfo(BorderItems) System.Windows.Data Warning: 101 : BindingExpression (hash=22226817): GetValue at level 0 from MainWindow (hash=3528959) using RuntimePropertyInfo(BorderItems): ObservableCollection`1 (hash=55866471 Count=0) System.Windows.Data Warning: 80 : BindingExpression (hash=22226817): TransferValue - got raw value ObservableCollection`1 (hash=55866471 Count=0) System.Windows.Data Warning: 89 : BindingExpression (hash=22226817): TransferValue - using final value ObservableCollection`1 (hash=55866471 Count=0) 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXmlLinq\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXmlLinq.dll'. Symbols loaded. 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXml\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXml.dll'. Symbols loaded. 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll'. Symbols loaded. System.Windows.Data Warning: 95 : BindingExpression (hash=22226817): Got PropertyChanged event from MainWindow (hash=3528959) System.Windows.Data Warning: 101 : BindingExpression (hash=22226817): GetValue at level 0 from MainWindow (hash=3528959) using RuntimePropertyInfo(BorderItems): ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 80 : BindingExpression (hash=22226817): TransferValue - got raw value ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 89 : BindingExpression (hash=22226817): TransferValue - using final value ObservableCollection`1 (hash=55866471 Count=1) 'test_wpf.vshost.exe' (CLR v4.0.30319: test_wpf.vshost.exe): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemData\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemData.dll'. Symbols loaded. System.Windows.Data Warning: 95 : BindingExpression (hash=22226817): Got PropertyChanged event from MainWindow (hash=3528959) System.Windows.Data Warning: 101 : BindingExpression (hash=22226817): GetValue at level 0 from MainWindow (hash=3528959) using RuntimePropertyInfo(BorderItems): ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 80 : BindingExpression (hash=22226817): TransferValue - got raw value ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 89 : BindingExpression (hash=22226817): TransferValue - using final value ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 95 : BindingExpression (hash=22226817): Got PropertyChanged event from MainWindow (hash=3528959) System.Windows.Data Warning: 101 : BindingExpression (hash=22226817): GetValue at level 0 from MainWindow (hash=3528959) using RuntimePropertyInfo(BorderItems): ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 80 : BindingExpression (hash=22226817): TransferValue - got raw value ObservableCollection`1 (hash=55866471 Count=1) System.Windows.Data Warning: 89 : BindingExpression (hash=22226817): TransferValue - using final value ObservableCollection`1 (hash=55866471 Count=1) The thread 0x3784 has exited with code 259 (0x103). The thread 0x3050 has exited with code 259 (0x103). The program '[12308] test_wpf.vshost.exe' has exited with code 0 (0x0).
What I have tried:
Main Class
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
namespace test_wpf
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public ObservableCollection<ItemDetail> BorderItems
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
DataContext = this;
BorderItems = new ObservableCollection<ItemDetail>();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if(BorderItems.Count == 0)
{
return;
}
BorderItems[0].X = 200;
BorderItems[0].Y = 300;
BorderItems[0].Width = 200;
BorderItems[0].Height = 100;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("BorderItems"));
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
ItemDetail d = new ItemDetail();
d.X = 100;
d.Y = 100;
d.Width = 100;
d.Height = 100;
d.Type = "text";
d.Text = "Test "+BorderItems.Count.ToString();
BorderItems.Add(d);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("BorderItems"));
}
}
}
MyCanvas
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace test_wpf
{
public class MyCanvas : InkCanvas
{
//Just a simple INotifyCollectionChanged collection
public ObservableCollection<ItemDetail> Source { get; set; }
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source",
typeof(ObservableCollection<ItemDetail>),
typeof(MyCanvas),
new FrameworkPropertyMetadata(new ObservableCollection<ItemDetail>(),
new PropertyChangedCallback(SourceChanged)));
//called when a new value is set (through binding for example)
protected static void SourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
//gets the instance that changed the "local" value
var instance = sender as MyCanvas;
//the new collection that will be set
ObservableCollection<ItemDetail> newCollection = args.NewValue as ObservableCollection<ItemDetail>;
//the previous collection that was set
ObservableCollection<ItemDetail> oldCollection = args.OldValue as ObservableCollection<ItemDetail>;
if (oldCollection != null)
{
//removes the CollectionChangedEventHandler from the old collection
oldCollection.CollectionChanged -= new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);
}
//clears all the previous children in the collection
instance.Children.Clear();
if (newCollection != null)
{
//adds all the children of the new collection
foreach (ItemDetail item in newCollection)
{
AddControl(item, instance);
}
//adds a new CollectionChangedEventHandler to the new collection
newCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(instance.collection_CollectionChanged);
}
}
//append when an Item in the collection is changed
protected void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//adds the new items in the children collection
foreach (ItemDetail item in e.NewItems)
{
AddControl(item);
}
}
protected static void AddControl(ItemDetail item, InkCanvas parentControl)
{
Border border = new Border();
border.DataContext = item;
border.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#000000"));
border.Width = item.Width;
border.Height = item.Height;
if(item.Type == "text")
{
TextBlock tb = new TextBlock();
tb.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFFF"));
tb.FontSize = 25;
tb.HorizontalAlignment = HorizontalAlignment.Center;
tb.VerticalAlignment = VerticalAlignment.Center;
Binding TextBinding = new Binding("Text");
TextBinding.Source = item;
TextBinding.Mode = BindingMode.TwoWay;
tb.SetBinding(TextBlock.TextProperty, TextBinding);
//tb.Text = item.Text;
border.Child = tb;
}
parentControl.Children.Add(border);
Binding XBinding = new Binding("X");
XBinding.Source = item;
XBinding.Mode = BindingMode.TwoWay;
Binding YBinding = new Binding("Y");
YBinding.Source = item;
YBinding.Mode = BindingMode.TwoWay;
border.SizeChanged += border_SizeChanged;
border.SetBinding(InkCanvas.LeftProperty, XBinding);
border.SetBinding(InkCanvas.TopProperty, YBinding);
}
private static void border_SizeChanged(object sender, SizeChangedEventArgs e)
{
Border border = sender as Border;
if (border == null)
{
throw new ArgumentException("Unexpected object. Expected border");
}
var i = border.DataContext;
ItemDetail itemDetail = i as ItemDetail;
if (itemDetail == null)
{
throw new ArgumentException("Unexpected object. Expected ItemDetail");
}
itemDetail.Width = border.ActualWidth;
itemDetail.Height = border.ActualHeight;
}
protected void AddControl(ItemDetail item)
{
AddControl(item, this);
}
static MyCanvas()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCanvas), new FrameworkPropertyMetadata(typeof(MyCanvas)));
}
public MyCanvas()
: base()
{
}
}
}
Item detail
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Controls;
namespace test_wpf
{
public class ItemDetail: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int X { get; set; }
public int Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public string Type { get; set; }
public string Text { get; set; }
}
}
MainClassWPF
<Window x:Class="test_wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:test_wpf"
Title="InkCanvasElementSelection"
ResizeMode="CanResize"
xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Height="800" Width="600">
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Left" Width="200" Orientation="Vertical">
<Line Margin="5"/>
<TextBlock>Create new Element</TextBlock>
<Button Click="Button_Click_1" Height="20" Content="New"/>
<Line Margin="5"/>
<TextBlock>Change Element 0</TextBlock>
<Button Click="Button_Click" Height="20" Content="Change"/>
</StackPanel>
<src:MyCanvas Source="{Binding Path=BorderItems, Mode=TwoWay}" Background="AliceBlue" EditingMode="Select"/>
</DockPanel>
</Window>
Hi,
solution was quite simple. Inkcanvas did not know about changes in ItemDetail class. The class ItemDetail was not observable. Just update class like
public class ItemDetail: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } private int _x; private int _y; private double _width; private double _height; private string _type; private string _text; public int X { get { return _x; } set { _x = value; NotifyPropertyChanged("X"); } } public int Y { get { return _y; } set { _y = value; NotifyPropertyChanged("Y"); } } public double Width { get { return _width; } set { _width = value; NotifyPropertyChanged("Width"); } } public double Height { get { return _height; } set { _height = value; NotifyPropertyChanged("Height"); } } public string Type { get { return _type; } set { _type = value; NotifyPropertyChanged("Type"); } } public string Text { get { return _text; } set { _text = value; NotifyPropertyChanged("Text"); } } }
and the code is functional.
Petr
这篇关于Wpf自定义inkcanvas绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!