c# - c# WPF 需要帮助:如何通过 WPF 显示对象中的值
问题描述
[2019-02-23编辑;我希望编辑问题是正确的]
我是 WPF 的新手,并且正在苦苦挣扎。我看过很多教程等,但没有找到答案(以我理解的方式)。
我正在构建一个 Yatzy 游戏,它自己的 Yatzy 类几乎完成了。现在我想在 yatzy 类中添加一个使用 WPF 的 GUI。
感谢 Reginald Blue 回答我的问题 v1 的意见。我正在研究视图模型。
Mark Whitall 做了一个很好的例子,但我无法将它迁移到我的需要:
但这也让我很困扰。我希望提供的代码是足够的,如果不是 - 问:-)
它看起来像我的视图模型,与我的模型有“联系”。那是超级但是关于我的视图连接到我的视图模型,似乎有问题。
作为开始,我想做什么:1)当字段 GameStatus 和 GameName 应该具有我的模型的默认值时。在制作我的视图模型之前,它工作得很好——但我把它搞砸了。我在 maincontrol.cs(在视图模型中)声明了我的 thisYatzy 对象。我应该在 app.xaml 级别声明它吗?2)当我点击“按钮”ShiftState时,我会调用我的视图模型来改变状态,并更新视图。但是从视图中我不能调用视图模型?
我希望我已经解释好了,你们中的某个人可以提供帮助:-)
看法:
应用程序.xalm
<Application x:Class="WPFYatzy.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFYatzy"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
应用程序.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFYatzy.Views
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
主窗口.xaml
<Window x:Class="MinimalMVVM.Views.ConvertWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Views="clr-namespace:WPFYatzy.Views"
xmlns:ViewModels="clr-namespace:WPFYatzy.ViewModel"
Title="YatzyGame - mainwindow"
MinWidth="300"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight">
<Window.DataContext>
<ViewModels:MainControl/>
</Window.DataContext>
<Views:Page1/>
</Window>
主窗口.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using YatzyGameCL;
namespace WPFYatzy
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//YatzyGame thisYatzy = new YatzyGame();
public MainWindow()
{
//InitializeComponent();
}
private void OnInit(object sender, EventArgs e)
{
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
page1.xaml
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFYatzy.Views
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
page1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFYatzy.Views
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
视图模型
ObservableObject.cs
using System.ComponentModel;
namespace WPFYatzy.ViewModel
{
public abstract class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
委托命令.cs
using System;
using System.Windows.Input;
namespace WPFYatzy.ViewModel
{
public class DelegateCommand : ICommand
{
private readonly Action _action;
public DelegateCommand(Action action)
{
_action = action;
}
public void Execute(object parameter)
{
_action();
}
public bool CanExecute(object parameter)
{
return true;
}
#pragma warning disable 67
public event EventHandler CanExecuteChanged { add { } remove { } }
#pragma warning restore 67
}
}
主控件.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using YatzyGameCL;
namespace WPFYatzy.ViewModel
{
class MainControl : ObservableObject
{
private YatzyGame thisYatzy = new YatzyGame();
private string _strGameName;
private string _strGameStatus;
public string GameName
{
get { return _strGameName; }
set
{
_strGameName = value;
RaisePropertyChangedEvent("GameName");
}
}
public string GameStatus
{
get { return _strGameStatus; }
set {
_strGameStatus = value;
RaisePropertyChangedEvent("GameStatus");
}
}
public void ShiftState()
{
thisYatzy.GameStatus.NextAround();
GameStatus = thisYatzy.GameStatus.ToString();
}
}
}
模型 YatzyGameCL.DLL
用于使框架“挂在一起”的方法
- thisYatzy.GameStatus
- thisYatzy.GameName
解决方案
这将很难简洁地表达。你应该去阅读 MVVM (Model-View-ViewModel) 模式。虽然将 MVVM 与 WPF 一起使用并不是绝对必要的,但对于您正在做的事情,它确实是您需要的地方。
具体来说:
您创建了一个模型。那是你的 YatzyGame。它知道 Yatzy 是如何工作的,拥有所有规则。这就是“游戏”。
你有一个观点。那是您的 XAML 文件(以及背后的代码)。它知道如何绘制屏幕,并且知道如何在被告知时进行更新。
但是……你没有 ViewModel。那是两个世界之间的桥梁。它知道如何告诉视图更新。您的模型不(也不应该)知道如何做到这一点,因此视图(屏幕)永远不会改变。
您的问题的非常具体的答案是您需要发送属性更改通知,以便视图知道属性(例如 GameStatus)已更改。你会很想在你的模型中这样做。不要那样做。
祝你好运!
推荐阅读
- php - AngularJS - $http GET 响应总是 [object Object]
- typescript - TypeScript:使用括号表示法访问对象道具时,类型“未定义”不能用作索引类型
- python - RTSP Streaming 未在 PyQT5 QMediaPlayer 中自动启动
- c++ - 如何使用 MSVC 命令行工具链正确编译和链接资源文件?
- ios - SwiftUI MapKit UIViewRepresentable MKLocalSearch 区域不起作用和集群
- ansible - ansible aws_ssm 查找失败并出现验证异常
- javascript - 如何在div之后添加一段文字?(反应js,引导)
- magento2 - 尝试安装 magento 2.6.p1 即使在删除分号后它仍显示缺少扩展错误
- pine-script - UNIX 中每个烛台的持续时间
- php - 为什么这个 cURL 脚本不起作用的任何想法