50

在架构上,我认为 WPF 非常棒。一般来说,我是底层渲染/动画内部工作的忠实粉丝。模板和样式设置的灵活性令人印象深刻。

但我讨厌 XAML - 我觉得它使很多事情复杂化。我已经在大型和小型应用程序上使用过它,并且我发现自己很多次都试图弄清楚如何在 XAML 中做一些基本原则是基本但语法很古怪的事情。不仅如此,我还多次想知道解析/绑定的某些部分有多重。(我知道它已编译,但我不确定在运行时仍评估多少)

XAML 只是构建和加载可视化树的一种方式。是否有任何框架可以简化以非 XML、基于代码(但仍主要是声明性)的方式构建可视化树?具体来说,我对在保留 MVVM 方法的同时缓解以下任何问题的框架感兴趣:

  1. 强类型绑定。指定 ViewModel 必须符合特定类型。我假设 BaseBinding 在引擎盖下使用反射,我对它的速度有点怀疑,更不用说破坏绑定很烦人。

  2. 更快的绑定,非INotifyPropertyChanged绑定。似乎BindableProperty<T>可以创建某种类型,并且绑定可以直接监听它,而不是接收所有 ViewModel 属性更改。并且使用直接回调与字符串参数似乎也是有利的。

  3. 不同的资源管理方法;同样,某种类型的强类型字典可能非常好。我几乎希望将样式视为 lambdas 或捕捉强类型方面的东西。

总而言之,任何不基于 XAML、非常适合 MVVM 并且是强类型的框架?

4

5 回答 5

31

我在无 Xaml 的 WPF 中支持你。我喜欢 WPF 的布局和绑定功能,但我也讨厌 XAML。我希望 WPF 可以用纯 C# 编写,有一些优点:

  • Object 和 Collection 初始化程序可以替换 Xaml 实例化。(遗憾的是,xaml 更喜欢自上而下而不是按钮向上)。
  • 绑定转换器可能只是 lambdas。
  • 样式可能只是在实例化后修改对象的 lambda,没有臃肿的<Setter>语法。
  • DataTemplates只是在给定对象的情况下创建控件的 lambdas
  • DataTemplateSelectors将只是一个调用其他 DataTemplate 的 DataTemplate lambda。
  • ItemsControl将只是一个 Foreach,它接受一个 lambda (DataTemplate) 并在将新项目添加到基础集合时再次调用它。
  • x:Names只是变量名。
  • 不需要很多 MarkupExtensions
    • x:静态
    • x:Type (特别是复杂的泛型!)
  • UserControls将只是功能。

我认为太多的复杂性被添加到 WPF 以允许它被设计。从过去的 FrontPage 到 Razor,Web 开发已经输掉了这场战斗。

于 2012-01-25T08:52:14.503 回答
8

简化?不可以。但是您可以在 XAML 中执行的所有操作都可以在代码中执行。例如,这是一个简单的 Windows Ink 绘图应用程序 - 非常简单:

谁需要视觉工作室? 紫色背景上的绿色墨水

没有保存,没有改变任何东西——但你可以通过代码。

画板.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Ink;

public class Sketchpad : Application {

    [STAThread]
    public static void Main(){
        var app = new Sketchpad();
        Window root = new Window();
        InkCanvas inkCanvas1 = new InkCanvas();

        root.Title = "Skortchpard";

        root.ResizeMode = ResizeMode.CanResizeWithGrip;
        inkCanvas1.Background = Brushes.DarkSlateBlue;
        inkCanvas1.DefaultDrawingAttributes.Color = Colors.SpringGreen;
        inkCanvas1.DefaultDrawingAttributes.Height = 10;
        inkCanvas1.DefaultDrawingAttributes.Width = 10;

        root.Content = inkCanvas1;
        root.Show();
        app.MainWindow = root;
        app.Run();
    }

}

画板.csproj

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
  <PropertyGroup>
    <AssemblyName>Simply Sketch</AssemblyName>
    <OutputPath>Bin\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xaml">
      <RequiredTargetFramework>4.0</RequiredTargetFramework>
    </Reference>
    <Reference Include="WindowsBase" />
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="SketchPad.cs" />
  </ItemGroup>
  <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
    <MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
  </Target>
    <Target Name="Clean">
    <Delete Files="$(OutputPath)$(AssemblyName).exe" />
  </Target>
  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

这就是它所需要的。当然,如果你想避免 XAML,这基本上意味着你将不得不编写一堆备用 .NET 代码,所以这取决于你 - 你想在 XAML 中转储这些东西,还是你愿意而是用代码写?

我认为在 VS 中执行此操作的最大好处是您可以获得良好的设计师支持,因此通常很容易直观地看到所有内容的位置和去向。它也可能更少查找文档,有时不得不做出一些飞跃。

但是没有 XAML 的 WPF是可能的

您甚至不需要为此安装 Visual Studio,只需 .NET CLI 和开发人员命令提示符即可。将这两个文件放在一个文件夹中并运行msbuild,然后您可以运行该目录中的Bin文件。

于 2018-09-21T13:20:12.210 回答
6

这个问题肯定需要一个指向Bling UI Toolkit的链接。这是一个超级天才的高级库,用于在 WPF 之上进行动画和丰富的 UI 原型设计。绑定button.Width = 100 - slider.Value,像这样的动画:button.Left.Animate().Duration(500).To = label.Right,像素着色器编译器 - 太棒了。

可悲的是,我认为该项目已不再进行。但是有很多非常聪明的想法可以让人深思。

于 2012-05-26T22:25:44.973 回答
2

WPF 没有这样的框架。您在愿望清单中提到的三件事将直接(和不同)替换 WPF 已经提供的组件。此外,用您的版本替换绑定和资源系统会使您喜欢的 WPF(动画、模板等)无法使用,因为它们严重依赖绑定、资源等。

以下是一些可以改善您体验的建议。
1. 学习处理 XAML(我以前也讨厌它的胆量,但现在我已经习惯了它很棒)
2. 构建你自己的库,让你在代码中轻松创建 UI。毕竟,在 XAML 中完成的所有事情也可以在代码中完成。
3. 如果你真的讨厌 INotifyPropertyChanged,并且想要一个回调而不是使用 DependencyProperty。没有事件让你引发,你可以有一个回调和默认值!
4.) 不要使用 WPF。即使您说您喜欢该架构,但您的缺点/期望的“改进”列表几乎涵盖了所有内容。

于 2011-04-20T15:19:45.657 回答
1
> non-INotifyPropertyChanged binding.

在您的视图模型或模型中手动实现 INotifyPropertyChanged需要大量的手动/重复工作。但是我读到了这些替代方案

  • DynamicViewModel: MVVM using POCOs with .NET 4.0:该项目旨在提供一种使用普通旧 CLR 对象 (POCO) 实现模型视图 ViewModel (MVVM) 架构模式的方法,同时充分利用 .NET 4.0 DynamicObject 类。利用 .NET 4.0 和 DynamicObject 类,我们可以创建派生自 DynamicObject 类的类型并在运行时指定动态行为。此外,我们可以在派生类型上实现 INotifyPropertyChanged 接口,使其成为数据绑定的良好候选者。

  • 更新控件 .NET:没有 INotifyPropertyChanged 的​​ WPF 和 Silverlight 数据绑定。它会自动发现依赖关系,因此您不必在视图模型中管理它们。它适用于 Winforms。使用事件通过代码绑定。

  • notifypropertyweaver:使用 IL 编织(通过http://www.mono-project.com/Cecil)将 INotifyPropertyChanged 代码注入属性。

    • 不需要属性
    • 无需参考
    • 不需要基类
    • 支持 .net 3.5、.net 4、Silverlight 3、Silverlight 4 和 Windows Phone 7
    • 支持客户端配置文件模式
于 2011-04-20T16:28:52.150 回答