要将Image
的 X 和 Y 坐标绑定到您的属性,请执行以下操作:
- 从 中删除
Char
的继承MainWindow
。
- 将
MainWindow
's设置DataContext
为Char
.
- 从
Visibility="Hidden"
_Canvas
例子:
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Char { iXCoordinate = 20, iYCoordinate = 50 };
}
}
确保您确实将iXCoordinate
andiYCoordinate
属性设置为某些东西。如果不是,它们将是 的默认值int
,即 0。例如,图像将显示在左上角。
要让视图 (UI) 知道绑定值何时发生更改,请在每次设置属性时实现INotifyPropertyChanged
并引发事件:PropertyChanged
public class Char : INotifyPropertyChanged
{
private int _iXCoordinate;
public int iXCoordinate
{
get { return _iXCoordinate; }
set
{
_iXCoordinate = value;
OnPropertyChanged("iXCoordinate");
}
}
private int _iYCoordinate;
public int iYCoordinate
{
get { return _iYCoordinate; }
set
{
_iYCoordinate = value;
OnPropertyChanged("iYCoordinate");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
这是最简单的实现方式INotifyPropertyChanged
。但是,我建议创建一个实现接口的基类,并让您的 ViewModels 从中继承。尝试这样的事情:
public class PropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var handler = PropertyChanged;
var propertyName = GetPropertyName(propertyExpression);
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
{
var unaryExpression = propertyExpression.Body as UnaryExpression;
if (unaryExpression == null)
throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
memberExpression = unaryExpression.Operand as MemberExpression;
}
if (memberExpression == null)
throw new ArgumentException("Expression must be a MemberExpression.", "propertyExpression");
var propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo == null)
throw new ArgumentException("Expression must be a Property.", "propertyExpression");
return propertyInfo.Name;
}
}
这PropertyChangedBase
还有一个额外的好处,即您必须PropertyChanged
使用 lambda 表达式而不是使用"magic strings"来引发事件,这很容易出现拼写错误并且不利于重构:
public int iYCoordinate
{
get { return _iYCoordinate; }
set
{
_iYCoordinate = value;
OnPropertyChanged(() => iYCoordinate);
}
}
但是,您真正的问题是ViewBox
包装Grid
.
AViewBox
测量它的孩子的大小Infinity
,然后按他们的大小排列它们DesiredSize
。这意味着它的孩子可以是他们想要的任何大小。两者Grid
都Canvas
没有他们想要的尺寸,他们依靠父母给他们一个尺寸。
要解决您的问题,请指定Width
其中Height
的Grid
或Canvas
内部的和。
顺便说一句:你知道的
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
会翻转你的卡瓦斯,对吧?