AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77786420
Accepted
Michael Chourdakis
Michael Chourdakis
Asked: 2024-01-09 19:26:11 +0800 CST2024-01-09 19:26:11 +0800 CST 2024-01-09 19:26:11 +0800 CST

WinUI3 C++ 数据绑定

  • 772

在参考我关于 TreeView 的问题时,建议我使用数据绑定来填充 TreView 的项目。

我在 Desktop C++ VS 2022 项目中创建了一个新的黑色应用程序、打包的 WinUI3。

这将运行并显示按钮

在此输入图像描述

我更改了 MainWindow IDL:

namespace App1
{
    [default_interface]
    runtimeclass MainWindow : Microsoft.UI.Xaml.Window, Microsoft.UI.Xaml.Data.INotifyPropertyChanged
    {
        MainWindow();
        String MyProperty;
    }
}

我改变了.h

namespace winrt::App1::implementation
{
    struct MainWindow : MainWindowT<MainWindow>
    {
        winrt::hstring j = L"TEXT 1";
        MainWindow()
        {
            // Xaml objects should not call InitializeComponent during construction.
            // See https://github.com/microsoft/cppwinrt/tree/master/nuget#initializecomponent
        }

        winrt::hstring MyProperty();
        void MyProperty(winrt::hstring);

        void myButton_Click(IInspectable const& sender, Microsoft::UI::Xaml::RoutedEventArgs const& args);

        winrt::event_token PropertyChanged(Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& value);
        void PropertyChanged(winrt::event_token const& token);
        winrt::event<Microsoft::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
    };
}

namespace winrt::App1::factory_implementation
{
    struct MainWindow : MainWindowT<MainWindow, implementation::MainWindow>
    {
    };
}

我更改.cpp:

#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif

using namespace winrt;
using namespace Microsoft::UI::Xaml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace winrt::App1::implementation
{
    winrt::hstring MainWindow::MyProperty()
    {
        return j;
    }

    void MainWindow::MyProperty(winrt::hstring nv)
    {
        j = nv;
        m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Content" });
    }


    winrt::event_token MainWindow::PropertyChanged(Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
    {
        return m_propertyChanged.add(handler);
    }

    void MainWindow::PropertyChanged(winrt::event_token const& token)
    {
        m_propertyChanged.remove(token);
    }


    void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
    {
        MyProperty(L"YO");
    }
}

最后是 XAML:

<Button x:Name="myButton" Click="myButton_Click" Content="{x:Bind MyProperty, Mode=OneWay}"></Button>

这只有效一次。它曾经调用我的属性并将“TEXT 1”设置为按钮,但是当调用时myButton_Click调用 m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"Content" });

什么也没做。该按钮不会更新其内容。

我究竟做错了什么?

编辑:当我m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L"" });这样做时,即没有“Content”字符串,它就可以工作。

为什么?

c++
  • 1 1 个回答
  • 42 Views

1 个回答

  • Voted
  1. Best Answer
    Simon Mourier
    2024-01-09T22:45:33+08:002024-01-09T22:45:33+08:00

    它不能双向工作,因为您指定了OneWay模式(实际上我真的不知道为什么,因为它应该在没有它的情况下工作......):

    <Button x:Name="myButton" Click="myButton_Click" Content="{x:Bind MyProperty, Mode=OneWay}"></Button>
    

    但你可以这样声明:

    <Button x:Name="myButton" Click="myButton_Click" Content="{x:Bind MyProperty, Mode=TwoWay}"></Button>
    

    但是,当您使用 C++/WinRT 执行此操作时,您可能会收到此类错误(请注意,在 .NET 和 C# 中,它会正常工作):

    MainWindow.xaml.g.hpp(155,71): error C2665: 'winrt::to_hstring': no overloaded function could convert all the argument types
    

    这是因为Contentis 是ObjectIDL 类型(又名IInspectable),而您的属性是StringIDL 类型(又名hstring),并且 没有带来隐式转换C++/WinRT,另请参阅https://github.com/microsoft/cppwinrt/issues/942

    因此,您可以通过创建此转换来修复它(模仿 C++/WinRT 的base.h to_hstring重载),例如在 MainWindow.xaml.h 中:

    WINRT_EXPORT 100,80,145,239,178,132
    e hstring to_hstring(IInspectable value)
      {
        auto pv = value.try_as<IPropertyValue>();
        if (pv && pv.Type() == PropertyType::String)
          return pv.GetString();
    
        return L"???";
      }
    }
    

    还要确保您的财产免受无限循环的影响:

    void MainWindow::MyProperty(hstring value)
    {
        if (_myProperty == value)
            return;
    
        _myProperty = value;
        RaisePropertyChanged(L"MyProperty");
    }
    

    我在这里创建了一个示例应用程序:https ://github.com/smourier/WinUI3Cpp

    • 1

相关问题

  • 为什么编译器在这里错过矢量化?

  • 使用带有库的 CMake 编译错误[关闭]

  • 每次我尝试运行预制时都会抛出错误

  • 如何在 C++ 中创建类似于 std::byte 的八位字节类型?

  • C++17 中 std::byte 只能按位运算?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve