のX座標とY座標をプロパティにバインドするには、Image
次のようにします。
Char
からの継承を削除しMainWindow
ます。
MainWindow
のDataContext
インスタンスを。に設定しますChar
。
- から削除
Visibility="Hidden"
しますCanvas
例:
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Char { iXCoordinate = 20, iYCoordinate = 50 };
}
}
iXCoordinate
とiYCoordinate
プロパティを実際に何かに設定していることを確認してください。そうでない場合は、デフォルト値の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
です。ただし、インターフェイスを実装する基本クラスを作成し、ViewModelにそれを継承させることをお勧めします。次のようなものを試してください。
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
public int iYCoordinate
{
get { return _iYCoordinate; }
set
{
_iYCoordinate = value;
OnPropertyChanged(() => iYCoordinate);
}
}
ただし、実際の問題は、ViewBox
をラップすることGrid
です。
のViewBox
サイズに子供を測定しInfinity
、次にそれらを彼らのによって配置しますDesiredSize
。これは、子供が好きなサイズになり得ることを意味します。どちらも、彼らが望むサイズを持っていませんGrid
、彼らは彼らにサイズを与えるために彼らの親に頼っています。Canvas
問題を解決するには、とを指定Width
しHeight
て、Grid
またはそのCanvas
中を指定します。
ところで:あなたはそれを知っています
<Canvas.LayoutTransform>
<ScaleTransform ScaleY="-1"/>
</Canvas.LayoutTransform>
あなたの洞窟をひっくり返しますよね?