我不明白为什么我无法将自定义宽度依赖项属性(我的自定义控件)绑定到另一个自定义控件依赖项属性。
我遵循了所有指导方针我非常确定依赖属性已得到很好的实施。
Window(BlackAndWhiteWindow),Canvas(所有这些都是自定义控件,而不是来自wpf的控件)都继承自控件。
有什么建议吗?我疯了......
Visual Studio错误声明无法绑定属性,因为您只能将依赖项属性绑定到依赖项对象,但它们是依赖项对象,并且我绑定到依赖项属性!!
编辑1:
XAML
<test:BlackAndWhiteWindow x:Class="GSdk.TestGsdkShared.TestWindow" x:Name="bwWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:windows="urn:gsdk-net"
xmlns:test="clr-namespace:GSdk.TestGsdkShared"
mc:Ignorable="d"
Width="320" Height="240"
d:DesignHeight="300" d:DesignWidth="300">
<windows:Canvas Width="{Binding ElementName=bwWindow, Path=Width}" Height="100">
</windows:Canvas>
</test:BlackAndWhiteWindow>
控制类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using GSdk.Net.Lglcd;
using System.Windows;
using System.Windows.Markup;
using System.Xaml;
using GSdk.Shared.Windows.Properties;
namespace GSdk.Shared.Windows
{
public class Control : DependencyObject, IDisposable
{
private volatile bool m_Disposing;
public Control()
{
/*Font = new Font(
"monospace",
12.0f,
System.Drawing.FontStyle.Bold
);*/
}
public static Property<Font> FontProperty = new Property<ContentControl, Font>(c => c.Font, new FrameworkPropertyMetadata(new Font("monospace", 12.0f, System.Drawing.FontStyle.Bold), FrameworkPropertyMetadataOptions.Inherits));
public static Property<int> WidthProperty = new Property<ContentControl, int>(c => c.Width, new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.Inherits));
public static Property<int> HeightProperty = new Property<ContentControl, int>(c => c.Height, new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.Inherits));
public Font Font
{
get { return FontProperty[this]; }
set
{
if (Font != null && Font != value)
Font.Dispose();
FontProperty[this] = value;
}
}
public int Width { get { return WidthProperty[this]; } set { WidthProperty[this] = value; } }
public int Height { get { return HeightProperty[this]; } set { HeightProperty[this] = value; } }
public virtual DeviceTypes DeviceType { get { return DeviceTypes.Invalid; } }
public bool Disposing { get { return m_Disposing; } protected set { m_Disposing = value; } }
#region Dispose handling
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
Disposing = true;
if (disposing)
{
// Managed resources
}
// Unmanaged resources
try
{
if (Font != null) Font.Dispose();
}
catch { }
}
~Control()
{
Dispose(false);
}
#endregion
}
}
画布类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using GSdk.Net.Lglcd;
using System.Windows;
using System.Windows.Markup;
using System.Xaml;
using GSdk.Shared.Windows.Properties;
namespace GSdk.Shared.Windows
{
public class Canvas : Layout, IDrawable
{
public Canvas()
: base()
{
}
public static Property<int> TopProperty = new AttachedProperty<Canvas, int>(() => TopProperty, new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.Inherits));
public static Property<int> LeftProperty = new AttachedProperty<Canvas, int>(() => LeftProperty, new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.Inherits));
public static Property<int> BottomProperty = new AttachedProperty<Canvas, int>(() => BottomProperty, new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.Inherits));
public static Property<int> RightProperty = new AttachedProperty<Canvas, int>(() => RightProperty, new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.Inherits));
public static void SetTop(DependencyObject obj, int value)
{
obj.SetValue(TopProperty, value);
}
public static int GetTop(DependencyObject obj)
{
return (int)obj.GetValue(TopProperty);
}
public static bool IsSetTop(DependencyObject obj)
{
return ((int)obj.GetValue(TopProperty) != default(int));
}
public static void SetLeft(DependencyObject obj, int value)
{
obj.SetValue(LeftProperty, value);
}
public static int GetLeft(DependencyObject obj)
{
return (int)obj.GetValue(LeftProperty);
}
public static bool IsSetLeft(DependencyObject obj)
{
return ((int)obj.GetValue(LeftProperty) != default(int));
}
public static void SetBottom(DependencyObject obj, int value)
{
obj.SetValue(BottomProperty, value);
}
public static int GetBottom(DependencyObject obj)
{
return (int)obj.GetValue(BottomProperty);
}
public static bool IsSetBottom(DependencyObject obj)
{
return ((int)obj.GetValue(BottomProperty) != default(int));
}
public static void SetRight(DependencyObject obj, int value)
{
obj.SetValue(RightProperty, value);
}
public static int GetRight(DependencyObject obj)
{
return (int)obj.GetValue(RightProperty);
}
public static bool IsSetRight(DependencyObject obj)
{
return ((int)obj.GetValue(RightProperty) != default(int));
}
public Bitmap Draw()
{
// FIXME: This should be changed, is temporary
//MessageBox.Show(Width.ToString() + " " + Height.ToString());
Bitmap tmp = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(tmp))
{
g.FillRectangle(Brushes.AliceBlue, 0, 0, Width, Height);
foreach (var item in Items)
{
int x, y;
x = y = 0;
IDrawable drawableItem = item as IDrawable;
DependencyObject dependencyItem = item as DependencyObject;
if (dependencyItem != null && drawableItem != null)
{
if (IsSetTop(dependencyItem))
y = GetTop(dependencyItem);
else if (IsSetBottom(dependencyItem))
y = Height - GetBottom(dependencyItem);
if (IsSetLeft(dependencyItem))
x = GetLeft(dependencyItem);
else if (IsSetRight(dependencyItem))
x = Width - GetRight(dependencyItem);
g.DrawImage(drawableItem.Draw(), x, y);
}
}
}
return tmp;
}
}
}
窗口类
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using GSdk.Net.Lglcd;
using System.Windows;
using System.Windows.Markup;
using System.Xaml;
using GSdk.Shared.Windows.Properties;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace GSdk.Shared.Windows
{
public abstract class Window : ContentControl, IDrawable
{
private Action m_DispatcherDrawHandler;
private Thread m_DrawThread;
private Bitmap Background = QvgaDevice.CreateValidBitmap();
public Window(Applet applet = null)
{
m_DispatcherDrawHandler = new Action(DispatcherDrawHandler);
if (DesignerProperties.GetIsInDesignMode(this))
{
Applet = new Applet()
{
Autostartable = false,
SupportedDevices = DeviceType,
Name = GetType().FullName,
};
Applet.Connect();
Applet.GetDevices<DefaultDeviceCollection>().Qvga.ForegroundApplet = true;
Applet.GetDevices<DefaultDeviceCollection>().Qvga.AppletPriority = AppletPriorities.Alert;
m_DrawThread = new Thread(new ThreadStart(DrawHandler));
m_DrawThread.Start();
//Dispatcher.Hooks.DispatcherInactive += new EventHandler(Hooks_DispatcherInactive);
}
else
{
Applet = applet ?? CreateApplet();
//if (Applet == null) throw new NullReferenceException("CreateApplet() must return a not null value");
}
}
private void DispatcherDrawHandler()
{
Applet.GetDevices<DefaultDeviceCollection>().Qvga.Update(Draw());
}
private void DrawHandler()
{
while (!Disposing)
{
Dispatcher.Invoke(m_DispatcherDrawHandler);
Thread.Sleep(33);
}
}
/*private void Hooks_DispatcherInactive(object sender, EventArgs e)
{
Dispatcher.Invoke(new Action(() =>
{
}));
}*/
protected abstract Applet CreateApplet();
//public readonly object SyncRoot = new object();
public Applet Applet { get; private set; }
public override DeviceTypes DeviceType { get { return DeviceTypes.Qvga; } }
public virtual Bitmap Draw()
{
using (Graphics g = Graphics.FromImage(Background))
{
g.FillRectangle(Brushes.Red, new Rectangle(0, 0, Background.Width, Background.Height));
g.DrawString("Hello World", Font, Brushes.White, new PointF(0f, 0f));
IDrawable ctrl = Content as IDrawable;
if (ctrl != null)
g.DrawImage(ctrl.Draw(), 0, 0);
}
return Background;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
lock (Applet)
if (Applet != null) Applet.Dispose();
}
}
}
物业类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Windows;
namespace GSdk.Shared.Windows.Properties
{
public struct Property<T>
{
Property(DependencyProperty prop)
{
m_DependencyProperty = prop;
}
readonly DependencyProperty m_DependencyProperty;
public static implicit operator Property<T>(PropertyBase prop)
{
return new Property<T>(prop.DependencyProperty);
}
public static implicit operator DependencyProperty(Property<T> prop)
{
return prop.m_DependencyProperty;
}
public T this[DependencyObject obj]
{
get { return (T)obj.GetValue(m_DependencyProperty); }
set { obj.SetValue(m_DependencyProperty, value); }
}
}
public abstract class PropertyBase
{
public readonly DependencyProperty DependencyProperty;
protected PropertyBase(DependencyProperty prop)
{
DependencyProperty = prop;
}
}
public sealed class Property<TContainer, TValue> : PropertyBase
{
public Property(Expression<Func<TContainer, TValue>> accessor)
: base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer)))
{
}
public Property(Expression<Func<TContainer, TValue>> accessor, PropertyMetadata metadata)
: base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer), metadata))
{
}
public Property(Expression<Func<TContainer, TValue>> accessor, PropertyMetadata metadata, ValidateValueCallback callback)
: base(DependencyProperty.Register(accessor.MemberToString(), typeof(TValue), typeof(TContainer), metadata, callback))
{
}
}
public sealed class AttachedProperty<TContainer, TValue> : PropertyBase
{
public AttachedProperty(Expression<Func<Property<TValue>>> accessor)
: base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0,accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer)))
{
}
public AttachedProperty(Expression<Func<Property<TValue>>> accessor, PropertyMetadata metadata)
: base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0, accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer), metadata))
{
}
public AttachedProperty(Expression<Func<Property<TValue>>> accessor, PropertyMetadata metadata, ValidateValueCallback callback)
: base(DependencyProperty.RegisterAttached(accessor.MemberToString().Substring(0, accessor.MemberToString().Length - "Property".Length), typeof(TValue), typeof(TContainer), metadata, callback))
{
}
}
}
答案 0 :(得分:1)
问题似乎与我正在使用一个模拟依赖项属性(属性结构)的类有关,而它不是直接依赖属性。通过使用正常依赖属性
解决