Wpf自定义inkcanvas绑定 [英] Wpf custom inkcanvas binding

查看:102
本文介绍了Wpf自定义inkcanvas绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我正在尝试将儿童收藏绑定到自定义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.Horizo​​ntalAlignment = Horizo​​ntalAlignment.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 >
< 按钮 单击 = Button_Click 高度 = 20 内容 = 更改 / >
< / 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆