我试图在WPF和C#中使用DataBinding做一件小事,但我无法理解DataBinding的任何教程..我的问题是,我在C#中有一个字符类,它有X和Y与get和set函数协调。然后我在窗口的画布中有一个图像,现在我试图将坐标从字符类绑定到图像。 (只有一个图像,并且只会创建一个字符类的实例,但不是在开头)。希望任何人都可以解释它,以便我完全理解它:/
编辑:
这是XAML:
<Window x:Class="ProjectChar.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="800" Width="1000" Background="Gray">
<Viewbox StretchDirection="Both" Stretch="Uniform">
<Grid>
<Canvas Name="Canv" Background="White" Visibility="Hidden" MaxHeight="750" MaxWidth="1000">
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
<Image Name="CharImage" Source="CharBild.png" Canvas.Left="{Binding iXCoordinate}" Canvas.Top="{Binding iYCoordinate}"/>
</Canvas>
</Grid>
</Viewbox>
这是C#-Part:
namespace ProjectChar
{
public class Char : MainWindow
{
public int iXCoordinate { get; set; }
public int iYCoordinate { get; set; }
}
}
所以我需要将它们绑定在一起,但我不知道如何。我知道我必须创建一个DataContext并且我需要将UpdateSource设置为PropertyChanged并且我需要一个EventHandler来更改Property,但我不知道如何做任何这些以及互联网上的教程都是说些不同的东西:/
答案 0 :(得分:3)
要将Image
的X和Y坐标绑定到您的属性,请执行以下操作:
Char
删除MainWindow
的继承。MainWindow
的{{1}}设置为DataContext
的实例。 Char
Visibility="Hidden"
醇>
示例:
Canvas
确保您实际将public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Char { iXCoordinate = 20, iYCoordinate = 50 };
}
}
和iXCoordinate
属性设置为某些内容。如果不是,它们将是iYCoordinate
的默认值,即0。图像将显示在左上角。
要让View(UI)知道绑定值何时发生更改,请在每次设置属性时实现INotifyPropertyChanged
并引发int
事件:
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));
}
}
的最简单方法。但是,我建议创建一个实现接口的基类,让ViewModel继承它。尝试这样的事情:
INotifyPropertyChanged
这个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;
}
}
还有一个额外的好处,你必须使用lambda表达式而不是使用"magic strings"来提升PropertyChangedBase
事件,这很容易出现拼写错误并且不利于重构:
PropertyChanged
但是,您的 REAL 问题是包裹 public int iYCoordinate
{
get { return _iYCoordinate; }
set
{
_iYCoordinate = value;
OnPropertyChanged(() => iYCoordinate);
}
}
的{{1}}。
ViewBox
测量它的大小为Grid
的孩子,然后按ViewBox
排列。Infinity
。这意味着它的孩子可以是他们想要的任何大小。 DesiredSize
和Grid
都没有想要的大小,他们依靠父母给他们一个大小。
要解决您的问题,请指定Canvas
或Width
内的Height
和Grid
。
BTW :你知道吗
Canvas
会翻转你的卡瓦斯,对吧?