【问题标题】:How do I set the Top and Left properties of a Rectangle in a Canvas如何在画布中设置矩形的顶部和左侧属性
【发布时间】:2020-08-29 18:35:32
【问题描述】:

所以我正在开发一个简单的“游戏”,如果你可以这样称呼它,它将是一个带有矩形的画布,当你按下W,A,S or D 时它会移动

就目前而言,它似乎正在改变矩形 Y 位置,但它没有在屏幕上更新,也就是画布中的矩形没有移动位置,我不知道为什么。

这是我的 Window.xaml

    <Window.InputBindings>
        <KeyBinding Command="{Binding WalkForwardCommand}" Key="W"/>
    </Window.InputBindings>


    <Window.DataContext>
        <viewModel:GameViewModel/>
    </Window.DataContext>

<Canvas Width="792" Height="420">

    <Rectangle Name="LocalPlayer"
               Fill="Crimson"
               Width="50" Height="50"
               Visibility="{Binding LocalPlayer.IsOnline }"
               
               Canvas.Top="{Binding LocalPlayer.Y }"
               Canvas.Left="{Binding LocalPlayer.X }" />
</Canvas>

这里是GameViewModel

public RelayCommand WalkForwardCommand { get; set; }

private Client _localPlayer;

public Client LocalPlayer
{
    get { return _localPlayer; }
    set
    {
        _localPlayer = value;

    }
}

public GameViewModel()
{
    

    WalkForwardCommand = new RelayCommand(o =>
    {
        LocalPlayer.Y -= 5;


        Debug.WriteLine("Walking up...");
        Debug.WriteLine(LocalPlayer.Y);
    });
}

还有Client.cs

class Client : ObservableObject
{
    public int X { get; set; }

    private int y;

    public int Y
    {
        get { return y; }
        set
        {
            y = value;
            OnPropertyChanged();
        }
    }
}

当然还有 ObservableObject

class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

该命令正在运行,因为它可以很好地打印到控制台,因此可以正确绑定。 但是由于某种原因,当 Y 值发生变化时,矩形不会切换位置。

为什么会这样,我该如何正确解决它?

【问题讨论】:

  • LocalPlayer = new Client(); 添加到GameViewModel 构造函数。你忘了实例化对象。并在LocalPlayer setter 中调用OnProperyChanged()
  • 根据你上面的例子,我尝试了一个快速测试,矩形正常上升。我不知道NotifyPropertyChangedInvocator 是什么,所以我不得不将其注释掉。同样在 ViewModel 上,我必须将客户端初始化为 private Client _localPlayer = new Client();。也许是别的原因?
  • 您是否有可能从外部实例化LocalPlayer,然后将其传递给ViewModel?如果是这种情况,您可能需要在它的 setter 中引发 OnPropertyChanged 事件。
  • Canvas.left 和 top 是 double 而不是 int。不确定那会有什么不同。你有 null for y 那里。如果你在它的声明中给 y 一个值 20 或其他值,这有什么不同吗?

标签: c# .net wpf mvvm


【解决方案1】:

尝试使LocalPlayer 成为您使用自动属性初始化程序初始化的只读属性:

 public Client LocalPlayer { get; } = new Client()

然后将Y的类型改为double

public double Y
{
    get { return y; }
    set
    {
        y = value;
        OnPropertyChanged();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-27
    • 2019-08-14
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    相关资源
    最近更新 更多