精华内容
下载资源
问答
  • WPF经典开发教程+WPF项目例子,对新手有一定的帮助,一些经典的语法和例子
  • wpf项目+数据库

    2018-01-15 17:43:50
    wpf项目包括wpf基础知识+wpf两个管理系统+水晶报表+数据库+Linq等技术
  • WPF项目书籍大合辑

    2018-01-19 17:40:31
    WPF的书籍文档,讲的非常的细致,值得一读所以便上传供大家借鉴
  • 下面就WPF项目框架搭建步骤一步一步的分享给大家。 在WPF项目开发中最常用的开发模式无疑是MVVM模式, MVVM模式开发的好处,在这里就不详细讨论, 还有 本文中所使用MVVMLight框架,为什么使用MVVM框架(1、框架较轻...
  • WPF项目搭建源代码

    2018-02-22 18:10:40
    http://www.cnblogs.com/yjwlogs/ 博客资源的项目源代码;
  • 例子完整准确,能够运行。
  • WPF 项目用例包括一个进销存系统 一个人力资源管理系统 wpf是微软新一代开发技术,涵盖了桌面应用程序开发、网络应用程序开发和移动应用程序开发,是微软开发技术未来十年的主要方向。 本书的内容分为两大部分。第一...
  • WPF项目-源码

    2021-02-18 08:28:19
    WPF项目
  • 可能你已发现一个问题,我们无法使用VS对WPF项目创建单元测试(VS2005不行,VS2008我没试过,但据说也不行),这让人很郁闷,这里将介绍如何使用NUnit来对WPF项目创建单元测试并解决其中的难题(但利用NUnit来对WPF创建...
  • 在Visual Studio Code中运行和调试WPF项目 在Visual Studio Code中运行和调试WPF项目时要考虑的特殊事项是: 在* .csproj中: 目标平台必须为x64: x64 ; PDB需要可移植:可移植 在* .xaml文件上设置生成器: ...
  • 20110402WPF 项目总结

    2011-04-02 19:14:04
    20110402WPF 项目总结 20110402WPF 项目总结 20110402WPF 项目总结
  • WPF项目小实例

    2012-06-14 19:35:21
    不需要实体类,直接进入数据库字段绑定,求值,前端显示。
  • 15个WPF项目开发经典例子,例子完整准确,能够运行。 WPF 倒计时+震动 示例_8416821 WPF_嵌入字体_EmbeddedFont_8408883 WPF3D切换例子_TimeZoneDaemonApp(3D)_8408869 WPF不规则按钮_8416707 WPF窗体缩放源码_...
  • mvvm框架 方便 快捷 遍历 强大功能的代码
  • mvvm框架 方便 快捷 遍历 强大功能的代码
  • 网上订餐实例,wpf+mvvm开发框架,点餐系统
  • MaterialDesign_WPF_Creator:用于创建Material Design WPF项目的WPF应用程序
  • C# WPF项目实战(经典)

    2021-05-01 00:00:55
    目的:输出两台摄像头图像和两路设备图像,每一路设备截图6张主要知识:1. 通过SDK调取摄像头图像,并对图像进行剪裁;2. WPF中定时器DispatcherTimer用法;3.WPF中...

    目的:输出两台摄像头图像和两路设备图像,每一路设备截图6张

    主要知识:

    1. 通过SDK调取摄像头图像,并对图像进行剪裁;

    2. WPF中定时器DispatcherTimer用法;

    3. WPF中跨线程访问控件方法

      Dispatcher.Invoke((Action)delegate {});

    区别于winform中

    this.Invoke((Action)delegate {});

    4.xml操作:

     XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\\config.xml");
                    XmlNode settingNode = xmlDoc.DocumentElement;
    
    
                    XmlElement e = settingNode.SelectSingleNode("DeviceType") as XmlElement;
                    if (e == null)
                    {
                        deviceType = "tps2000";
                    }
                    else
                    {
                      deviceType = e.InnerText;
                    }
    

    5. 带多个参数的委托

                DP1 = new DataProcess(DeviceIP1, LocalPort1,0);
                DP1.ShowEvent1 = DrawControls1;
                DP1.Start();//启动线程
    

    6.多线程操作

                Thread t1 = new Thread(new ThreadStart(DataRevThread));                  //开启DataRevThread
                t1.Name = "DataRevThread";                                            //线程名字
                t1.Start();
                t1.IsBackground = true;                                                  //后台运行
    

    7. UDP接收,解码;

    8. emgucv使用;

    9. 工厂模式:

    
    
       ModelFactory MF = new ModelFactory();
       DM = MF.CreateDataModelFactory_v1(sNeed.ToString());
    

    10.信号量线程间同步

    Semaphore TaskSemaphoreData = new Semaphore(0, 2560);           //数据缓存队列缓存区
     TaskSemaphoreRev.WaitOne();                //等待接收队列
    

    11.Bitmap转换为ImageSource

     [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
    
    
            public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap)
            {
                IntPtr hBitmap = bitmap.GetHbitmap();
                ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    
    
                if (!DeleteObject(hBitmap))
                {
                    throw new System.ComponentModel.Win32Exception();
                }
                return wpfBitmap;
            }
    

    12.Queue和list的操作

    包括但是不限于以上内容

    代码如下:

    MainWindow.xaml:

    <Fluent:RibbonWindow x:Class="thzSoftware.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:Fluent="urn:fluent-ribbon"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
            xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
            xmlns:local="clr-namespace:thzSoftware"
            mc:Ignorable="d"
            Title="MainWindow" Height="600" Width="800" WindowStartupLocation="CenterScreen" WindowState="Maximized" Background="LightBlue" Closing="RibbonWindow_Closing">
        <Grid ShowGridLines="True" >
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="10*"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="10*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0" Name="labelCamera1Status" Content="摄像头连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
            <wfi:WindowsFormsHost Grid.Row="1" Grid.Column="0" Background="LightGray">
                <wf:PictureBox x:Name="Cam1" />
            </wfi:WindowsFormsHost>
            <Label Grid.Row="2" Grid.Column="0" Name="labelCamera2Status"  Content="摄像头连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
            <wfi:WindowsFormsHost Grid.Row="3" Grid.Column="0" Background="LightGray">
                <wf:PictureBox x:Name="Cam2" />
            </wfi:WindowsFormsHost>
            <Label Grid.Row="0" Grid.Column="1" Name="labelThz1Status"  Content="太赫兹连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
            <Image Grid.Row="1" Grid.Column="1" Name="Thz1"  />
            <Label Grid.Row="2" Grid.Column="1" Name="labelThz2Status"  Content="太赫兹连接状态" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="LightCyan"/>
            <Image Grid.Row="3" Grid.Column="1" Name="Thz2" />
           
            <Image Grid.Row="1" Grid.Column="2" Name="Thz1Image1" />
            <Image Grid.Row="1" Grid.Column="3" Name="Thz1Image2" />
            <Image Grid.Row="1" Grid.Column="4" Name="Thz1Image3" />
            <Image Grid.Row="1" Grid.Column="5" Name="Thz1Image4" />
            <Image Grid.Row="1" Grid.Column="6" Name="Thz1Image5" />
            <Image Grid.Row="1" Grid.Column="7" Name="Thz1Image6" />
            <Image Grid.Row="3" Grid.Column="2" Name="Thz2Image1" />
            <Image Grid.Row="3" Grid.Column="3" Name="Thz2Image2" />
            <Image Grid.Row="3" Grid.Column="4" Name="Thz2Image3" />
            <Image Grid.Row="3" Grid.Column="5" Name="Thz2Image4" />
            <Image Grid.Row="3" Grid.Column="6" Name="Thz2Image5" />
            <Image Grid.Row="3" Grid.Column="7" Name="Thz2Image6" />
        </Grid>
    </Fluent:RibbonWindow>
    
    
    

    MainWindow.xaml.cs

    using System;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Windows.Threading;
    using MessageBox = System.Windows.MessageBox;
    using thzModel;
    using System.Drawing;
    using System.Windows;
    using System.Windows.Media.Imaging;
    using System.Windows.Media;
    using System.Xml;
    using Emgu.CV;
    using Emgu.CV.Structure;
    using System.Threading;
    using System.Drawing.Imaging;
    using System.Collections.Generic;
    using System.Windows.Controls;
    using Image = System.Windows.Controls.Image;
    
    
    namespace thzSoftware
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Fluent.RibbonWindow
        {
            DispatcherTimer Cam1ReconnectTimer, Cam2ReconnectTimer;
            public MainWindow()
    {
                try
                {
                    InitializeComponent();
                    Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
                    
                    init();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace + ex.Message);
    
    
                    LogWrite.logWrite(ex.Message, ex.StackTrace);
    
    
                }
            }
    
    
            public IntPtr PictureDev1Cam { get { return Cam1.Handle; } }
            public IntPtr PictureDev2Cam { get { return Cam2.Handle; } }
            IntPtr Cam1Handle = IntPtr.Zero;
            IntPtr Cam2Handle = IntPtr.Zero;
            Camera Camera1 = new Camera();
            Camera Camera2 = new Camera();
            static private string Cam1IP = "192.168.1.64";
            static private string Cam2IP = "192.168.1.61";
            DataProcess DP1 = null, DP2 = null;
            object ThreadLockBitmap = new object();
            List<ImageSource> thzBitmapList1 = new List<ImageSource>();
            List<ImageSource> thzBitmapList2 = new List<ImageSource>();
            int snapFlag1 = 0, snapFlag2 = 0;
            static public String DeviceType
            {
                get
                {
                    return deviceType;
                }
                set
                {
                    deviceType = value;
                }
            }
            static private string deviceType = "tps2000";
    
    
            void init()
    {
                ReadConfigXML();
                Cam1Handle = PictureDev1Cam;
                Cam2Handle = PictureDev2Cam;
                Cam1.SizeMode = PictureBoxSizeMode.Zoom;
                Cam2.SizeMode = PictureBoxSizeMode.Zoom;
    
    
                Cam1ReconnectTimer = new DispatcherTimer();
                Cam1ReconnectTimer.Interval = new TimeSpan(0, 0, 3);//定时间隔3秒
                Cam1ReconnectTimer.Tick += Cam1ReconnectTimer_Tick;//加载事件,敲tab键事件框架可以自己出来
                Cam1ReconnectTimer.Start();
    
    
                Cam2ReconnectTimer = new DispatcherTimer();
                Cam2ReconnectTimer.Interval = new TimeSpan(0, 0, 3);//定时间隔3秒
                Cam2ReconnectTimer.Tick += Cam2ReconnectTimer_Tick;//加载事件,敲tab键事件框架可以自己出来
                Cam2ReconnectTimer.Start();
    
    
                thzModel.Command.CommandUp(8);//发送启动指令
    
    
                string DeviceIP1 = "192.168.1.110";
                int LocalPort1 = 8007;
                DP1 = new DataProcess(DeviceIP1, LocalPort1,0);
                DP1.ShowEvent1 = DrawControls1;
                DP1.Start();//启动线程
    
    
                string DeviceIP2 = "192.168.1.120";
                int LocalPort2 = 8009;
                DP2 = new DataProcess(DeviceIP2, LocalPort2, 1);
                DP2.ShowEvent2 = DrawControls2;
                DP2.Start();//启动线程
    
    
            }
            private void DrawControls1(Bitmap image, bool isWarning, bool isBlack)
    {
                Image[] iSource = { Thz1Image1, Thz1Image2, Thz1Image3, Thz1Image4, Thz1Image5, Thz1Image6 };
                Dispatcher.Invoke((Action)delegate
                {
                    labelThz1Status.Content = "太赫兹连接成功";
                    Thz1.Source = ChangeBitmapToImageSource(image);
    
    
                    snapFlag1++;
                    thzBitmapList1.Add(Thz1.Source);
                    if (thzBitmapList1.Count > 6)
                        thzBitmapList1.RemoveAt(0);
                    if (snapFlag1 > 8)
                    {
                        snapFlag1 = 0;
                        for (int i = 0; i < thzBitmapList1.Count; i++)
                        {
                            iSource[i].Source = thzBitmapList1[i];
                        }
                    }
    
    
                });
            }
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
    
    
            public static ImageSource ChangeBitmapToImageSource(Bitmap bitmap)
    {
                IntPtr hBitmap = bitmap.GetHbitmap();
                ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
    
    
                if (!DeleteObject(hBitmap))
                {
                    throw new System.ComponentModel.Win32Exception();
                }
                return wpfBitmap;
            }
            private void DrawControls2(Bitmap image, bool isWarning, bool isBlack)
    {
                Image[] iSource = { Thz2Image1, Thz2Image2, Thz2Image3, Thz2Image4, Thz2Image5, Thz2Image6 };
                Dispatcher.Invoke((Action)delegate 
                {
                    labelThz2Status.Content = "太赫兹连接成功"; 
                    Thz2.Source = ChangeBitmapToImageSource(image);
    
    
                    snapFlag2++;
                    thzBitmapList2.Add(Thz2.Source);
                    if (thzBitmapList2.Count > 6)
                        thzBitmapList2.RemoveAt(0);
                    if (snapFlag2 > 8)
                    {
                        snapFlag2 = 0;
                        for (int i = 0; i < thzBitmapList2.Count; i++)
                        {
                            iSource[i].Source = thzBitmapList2[i];
                        }
                    }
                });
            }
    
    
            private void ReadConfigXML()
    {
                try
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\\config.xml");
                    XmlNode settingNode = xmlDoc.DocumentElement;
    
    
                    XmlElement e = settingNode.SelectSingleNode("DeviceType") as XmlElement;
                    if (e == null)
                    {
                        deviceType = "tps2000";
                    }
                    else
                    {
                      deviceType = e.InnerText;
                    }
                }
                catch (Exception ex)
                {
                    LogWrite.logWrite(ex.Message, ex.StackTrace);
                }
            }
            private void ConnectCamera(int whitch)
    {
                try
                {
                    string userName = "admin";
                    string password = "a123456.";
                    int PortCamera = 8000;
                    if (whitch == 1)
                    {
                        labelCamera1Status.Content = "摄像头连接中...";
                        Task.Run(() =>
                        {
                            if (!Camera1.ConnectCamera(Cam1IP, PortCamera, userName, password))
                            {
                                Dispatcher.Invoke((Action)delegate { labelCamera1Status.Content = "摄像头连接失败"; });
                            }
                            else
                            {
                                Dispatcher.Invoke((Action)delegate { labelCamera1Status.Content = "摄像头连接成功"; });
                                Camera1.Preview(Cam1Handle);
                                Camera1.AdjustMirrorPara(1);
                                Cam1ReconnectTimer.Stop();
                            }
                        });
                    }
                    else
                    {
                        labelCamera2Status.Content = "摄像头连接中...";
                        Task.Run(() =>
                        {
                            if (!Camera2.ConnectCamera(Cam2IP, PortCamera, userName, password))
                            {
                                Dispatcher.Invoke((Action)delegate { labelCamera2Status.Content = "摄像头连接失败"; });
                            }
                            else
                            {
                                Dispatcher.Invoke((Action)delegate { labelCamera2Status.Content = "摄像头连接成功"; });
                                Camera2.Preview(Cam2Handle);
                                Camera2.AdjustMirrorPara(1);
                                Cam2ReconnectTimer.Stop();
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                   MessageBox.Show(ex.StackTrace + ex.Message);
                   LogWrite.logWrite(ex.Message, ex.StackTrace);
                }
            }
            private void Cam1ReconnectTimer_Tick(object sender, EventArgs e)
    {
                ConnectCamera(1);
    
    
            }
    
    
            private void RibbonWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
                thzModel.Command.CommandUp(0);//发送停止指令
                //Application.Exit();
    
    
    
    
            }
    
    
            private void Cam2ReconnectTimer_Tick(object sender, EventArgs e)
    {
                ConnectCamera(2);
            }
    
    
           
    
    
        }
    
    
    }
    
    
    

    其余部分代码太长,不贴了,需要的话自己下载:百度网盘

    链接:https://pan.baidu.com/s/1k2F0C-0gXX-tK_32m_ksOA 

    提取码:abs5 

    展开全文
  • WPF装载机 在WPF项目中使用的动画加载程序的集合。 您知道,出于娱乐,因为有时候我很无聊。 在可用! PM > Install-Package MrMitch.Loaders 当我发现一些时间时,我将添加一些文档。
  • WPF项目实例-MVVM,wpf项目实例pdf,C#源码.zip
  • WPF项目实例-MVVM,wpf项目实例pdf,C#源码.rar
  • ReactiveUi-CastleWindsor适配器 使用ReactiveUI,Castle Windsor和MahApps的示例WPF项目
  • vs创建wpf项目

    千次阅读 2018-11-16 10:14:32
    vs创建wpf项目 找到我们的应用Wpf,我勾选了为解决方案创建项目,在默认的路径下创建了该项目。 我们可以看到,设计界面的代码. 查看我们的工具箱,看到我们有wpf控件 这些控件和我们winform一样只要拖进去vs就...

    vs创建wpf项目

    创建界面一

    找到我们的应用Wpf,我勾选了为解决方案创建项目,在默认的路径下创建了该项目。

    创建界面二

    创建完成

    我们可以看到,设计界面的代码.

    设计代码

    查看我们的工具箱,看到我们有wpf控件

    工具箱

    这些控件和我们winform一样只要拖进去vs就会帮我们自动生成代码
    如下图箭头所指:

    button

    展开全文
  • CMDemo 使用Caliburn.Micro框架的WPF项目存储库,用于实现MVVM体系结构标准
  • `C++/CLI`下创建WPF项目的方法`C++/CLI`下创建WPF项目的方法 C++/CLI下创建WPF项目的方法 Visual C++中创建WPF项目的方法 由于WPF不仅仅支持C#/VB开发,还支持其他语言,比如: C++、F#等开发,于是大白我最近花了点...

    C++/CLI下创建WPF项目的方法

    Visual C++中创建WPF项目的方法


    由于WPF不仅仅支持C#/VB开发,还支持其他语言,比如: C++、F#等开发,于是大白我最近花了点时间摸索了一下,本文主要介绍C++/CLI下创建WPF项目的方法。

    我使用的开发环境是: Win10 x64 + Visual Studio 2019 (16.6.1版本)。

    今天我们需要使用C++/CLI,算是C++的一个子集吧。

    要能正常使用C++/CLI,首先需要确保你安装了C++/CLI build套件(见下图),同时还需要确保你安装好了Visual C++相应版本的运行库。

    进入控制面板,找到 Visual Studio 2019,右击"修改",然后切换到"独立组件"(Individual components)这个选项卡。

    img1

    如果没安装,勾选后安装一下即可。

    接下来我们可以创建项目了,建议选用模板 CLR Empty Project (.NET Framework),解决方案和项目名可以都用CppWpfDemo

    img2

    这时一个空项目就创建完成了。

    此时查看 Project的属性,Configration Properties -> “C/C++” -> “All Options”,输入 "common"进行搜索,确保选中的是 Common Language Runtime Suppor(/clr).

    img3

    接下来我们鼠标右击项目下的文件夹"Resource Files",点"Add" -> “new item”,类型选"Component Class",可使用默认的名字MyComponent

    img4

    此时,MyComponent.cpp中的代码如下:

    #include "MyComponent.h"
    

    为了正确引用到 WPF 中的各种库,我们还需要加入 WPF中 3 个核心的 dll,操作方法是:

    右键点击项目中的 References,然后点 Add Reference,勾选上:

    • PresentationCore
    • PresentationFramework
    • WindowsBase

    img5

    接下来,进行了一番倒腾,我改成了这个,做成了一个简单的界面:

    此时 MyComponent.cpp的内容如下:

    #include "MyComponent.h"
    
    using namespace CppWpfDemo;
    using namespace System::Windows;
    using namespace System::Windows::Controls;
    using namespace System::Windows::Media;
    
    [System::STAThreadAttribute]
    int main(array<System::String^>^ args)
    {
    	Application^ app = gcnew Application();
    	Window^ window = gcnew Window();
    	window->Title = "C++/CLI WPF demo";
    
    	TextBlock^ tb = gcnew TextBlock();
    	tb->Text = "Hello WPF";
    
    	// Add root Grid
    	Grid^ rootGrid = gcnew Grid();
    	rootGrid->Width = 120;
    	rootGrid->Height = 120;
    	RowDefinition^ myRowDef1 = gcnew RowDefinition();
    	rootGrid->RowDefinitions->Add(myRowDef1);
    
    	DataGrid^ grid = gcnew DataGrid();
    	grid->Background = Brushes::LightBlue;
    	grid->Width = 80;
    	grid->Height = 100;
    
    	// Define the Canvas
    	Canvas^ mainCanvas = gcnew Canvas();
    	mainCanvas->Children->Add(tb);
    	mainCanvas->Children->Add(grid);
    
    	Canvas::SetTop(tb, 20);
    	Canvas::SetLeft(tb, 20);
    
    	Canvas::SetTop(grid, 50);
    	Canvas::SetLeft(grid, 20);
    
    	rootGrid->Children->Add(mainCanvas);
    	Grid::SetRow(mainCanvas, 0);
    
    	window->Content = rootGrid;
    	app->Run(window);
    
    	return 0;
    }
    

    代码中的[STAThread]是需要的,表示Single Thread Apartment(单线程单元),等价于[System::STAThread][System::STAThreadAttribute],更多相关介绍见文末。

    还有个朋友说需要在项目属性中设置"Entry Point"的值为"main",测试过了填与不填没影响,建议别填。

    image6

    接下来,可以build了。

    如果出现VCRUNTIME140.dll missing的问题,安装一下Visual C++ Redistributable for Visual Studio 2015Microsoft Visual C++ 2015 Redistributable Update 3 RC 可以解决,x64和x86的运行库都需要安装。

    如果还不行,

    • 下载 VCRUNTIME140.DLL
    • 以管理员权限复制这个 dll 到 C:\Windows\System32
    • 检查该 dll 的文件读写权限是否为只读,如果是只读,去掉前面的勾勾.

    此时按F5(或 Ctrl + F5),运行结果如下:

    image9

    美中不足的是后面一直有个命令行窗口。


    启动时如何设置才能只显示WPF界面?

    那么问题来了,F5启动时如何设置才能只显示WPF界面?
    网上找了下解决方案,发现将目前用的 int main()改为int WINAPI WinMain() 可以解决,要能使用WinMain()则需要引入windows.h头文件。

    当把 #include windows.h加到#include "MyComponent.h"下一行时,发现如下错误:

    image7

    原因在于命令空间冲突,使得Window的引用出现起义。

    解决方法是: 将 #include windows.h放在代码的第一行。

    此时,此时 MyComponent.cpp的内容如下:

    #include "windows.h"
    #include "MyComponent.h"
    
    using namespace System::Windows;
    using namespace System::Windows::Controls;
    using namespace System::Windows::Media;
    
    [STAThread]
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    	LPSTR lpCmd, int nCmd)
    {
    	Application^ app = gcnew Application();
    	Window^ window = gcnew Window();
    	window->Title = "C++/CLI WPF demo";
    
    	TextBlock^ tb = gcnew TextBlock();
    	tb->Text = "Hello WPF";
    
    	// Add root Grid
    	Grid^ rootGrid = gcnew Grid();
    	rootGrid->Width = 120;
    	rootGrid->Height = 120;
    	RowDefinition^ myRowDef1 = gcnew RowDefinition();
    	rootGrid->RowDefinitions->Add(myRowDef1);
    
    	DataGrid^ grid = gcnew DataGrid();
    	grid->Background = Brushes::LightBlue;
    	grid->Width = 80;
    	grid->Height = 100;
    
    	// Define the Canvas
    	Canvas^ mainCanvas = gcnew Canvas();
    	mainCanvas->Children->Add(tb);
    	mainCanvas->Children->Add(grid);
    
    	Canvas::SetTop(tb, 20);
    	Canvas::SetLeft(tb, 20);
    
    	Canvas::SetTop(grid, 50);
    	Canvas::SetLeft(grid, 20);
    
    	rootGrid->Children->Add(mainCanvas);
    	Grid::SetRow(mainCanvas, 0);
    
    	window->Content = rootGrid;
    	app->Run(window);
    
    	return 0;
    }
    

    而运行结果为:

    image8

    大白今天躺坑完毕,总算解决了问题,先酱~

    第一个版本代码已上传到 github: https://github.com/yanglr/CppWpfDemo/tree/master/CppWpfDemo/CppWpfDemo.


    线程化与“套间”(单元)

    STAThreadAttribute 类:指示应用程序的 COM 线程模型是单线程单元 (STA)。

    一个进程加载了一个COM的DLL文件后,该DLL可能定义并使用了一些可修改的全局变量或访问共享资源。该进程内的多个线程如何并发访问该DLL并保证是线程安全的,这就是“套间”(apartment)技术需要解决的问题。

    COM对象与创建或调用COM对象的线程可以按两种策略来实现并发安全:

    • 按照单线程执行方式写COM对象的代码,完全不考虑并发执行问题。这样的每个COM对象只能由一个线程执行,该线程通过Windows消息队列实现多线程访问该COM对象被串行化从而并发安全。这种策略称作单线程套间(Single-Threaded Apartment,STA)。
    • COM对象的代码自身实现了并发控制(通过Windows互斥原语,如互斥锁临界区事件信号量等)。因此实际上多线程可以直接调用该COM对象的方法,这是并发安全的。这种策略称作多线程套间(Multi-Threaded Apartment,MTA)。

    COM的并发安全的具体实现,提出了套间(apartment)概念。每一种套间类型表示在一个进程内部是多线程情况下,如何同步对COM对象的调用。套间是一个逻辑容器,收纳遵循相同线程访问规则的COM对象与COM线程(创建了COM对象的线程或者调用了COM对象的方法的线程)。套间本质上只是一个逻辑概念而非物理实体,没有句柄类型可以引用它,更没有可调用的API操纵它。套间有两种:

    • 单线程套间(Single-Threaded Apartment,STA):每个进程可以有多个STA套间。每个STA套间只能有一个线程。每个STA性质的COM对象只能属于一个STA套间。一个STA套间可以有零个或多个STA属性的COM对象,这些COM对象的方法只能由该套间的唯一线程执行。STA套间的线程可以直接调用该套间的COM对象的方法。如果STA套间的COM对象被套间外的线程或进程调用,那么该套间的线程必须实现Windows消息队列与消息循环处理机制,其他线程必须通过marshalling与unmarshalling机制,通过给该STA套间的线程发送Windows消息来调用COM对象。每个STA性质的线程自动形成一个STA套间,这个套间容纳了该线程及其创建的所有STA性质COM对象。MTA性质的线程创建STA性质的COM对象时,系统自动把该COM对象放在default STA套间内,由该套间的STA线程来执行该COM对象的方法。每个进程至多有一个default STA套间,该套间与套间内线程是自动生成的。
    • 多线程套间(Multi-Threaded Apartment,MTA):每个进程至多有一个MTA套间。所有MTA性质的线程都属于MTA套间。所有MTA性质的COM对象也都属于这个MTA套间。STA性质的线程创建MTA性质的COM对象时,系统自动创建一些线程以执行这些MTA性质的COM对象,这些线程也属于MTA套间,系统返回安整后的COM对象的描述给STA性质的线程。

    一个COM对象只能存在于一个套间。COM对象一经创建就确定所属套间,并且直到销毁它一直存在于这个套间。COM对象有4种套间模式:单线程套间(Single Threading Apartment,STA),多线程套间(MTA),线程中立套间(Thread Neutral Apartment,NA),以及Both(STA+MTA)。详见下表。COM对象的套间类型写在Windows注册表相关条目中。

    一个COM线程从创建到结束都属于同一个套间。COM线程只有两种套间模式:STA或MTA。[13]线程必须通过调用CoInitializeEx()函数并且设定参数为COINIT_APARTMENTTHREADED或者COINIT_MULTITHREADED,来指明该线程的套间模式。调用了CoInitializeEx()函数的线程即已进入套间,直到线程调用CoUninitialize()函数或者自身终止,才会离开套间。COM为每个STA的线程自动创建了一个隐藏窗口,其Windows class是"OleMainThreadWndClass" 。跨套间调用这个STA套间内的COM对象,实际上是向这个隐藏窗口发送了一条窗口消息,通过消息循环与分派,该窗口过程收到这条窗口消息并调用相应的COM对象的接口方法。

    线程与属于同一套间的对象遵循相同的线程访问规则,可以直接执行方法调用而不需COM的辅助。线程跨套间边界去调用COM对象,传递的指针需要marshalling。如果通过标准的COM的API来调用,可以自动完成安整。例如,把一个COM接口指针作为参数传递给另外一个套间的COM对象的proxy的情形。但如果软件编程者跨套间传递接口指针而没有使用标准COM机制,就需要手工完成安整(通过CoMarshalInterThreadInterfaceInStream函数)与反安整(通过CoGetInterfaceAndReleaseStream函数获取COM接口的proxy)。例如,把COM接口指针作为线程启动时的参数传递的情形。

    跨进程的调用COM对象类似于同一进程内跨套间的调用COM对象。

    Object Linking & Embedding (OLE,对象链接与嵌入技术)提供了如下几种套间:

    套间类型描述
    单线程套间[14]STA),(ThreadingModel=Apartment一个单独的线程专门用于执行COM对象的方法。如果是STA的COM线程创建了STA的COM对象,这个COM对象的方法就由该线程执行,该线程调用该COM对象是直接调用。如果MTA的COM线程创建了STA的COM对象,系统在当前进程内自动创建一个default STA线程来执行该STA的COM对象的方法,并把COM对象的proxy返回该MTA的线程。COM对象所在STA套间之外的线程调用该COM对象的方法,需要对COM对象的指针先做marshalling再由操作系统自动排队(通过该COM对象被调用方法所在的线程的标准的Microsoft Windows的訊息迴圈)。这提供了自动同步以确保对象的方法每次调用执行完毕后才能启动方法的新的调用。开发者不需要担心线程加锁(locking)或競態條件。如果跨套间调用STA的COM对象,该对象所在STA的线程必须提供线程消息循环处理机制。
    多线程套间[15]MTA),(ThreadingModel=FreeCOM运行时不提供同步,多个MTA线程可以同时调用同一个MTA的COM对象,由各个MTA线程直接执行COM对象的方法,且因为在同一个MTA中因此不需要安整。COM对象需要自己实现同步控制以避免多线程同时访问造成的競態條件或死锁。STA的线程创建MTA的COM对象,系统自动创建一个或多个线程来执行MTA的COM对象。STA线程调用MTA的COM对象也需要marshalling,系统自动分配某个自动创建的线程来执行COM对象。MTA的优点是提高了并发处理性能,同时工作线程不需要有自己的Windows消息循环
    自动选择套间[16],(ThreadingModel=BothCOM对象创建时系统自动选择STA或MTA,以匹配主调线程的套间类别。这避免了很多marshalling开销,例如一个MTA服务器被一个STA线程调用。
    Thread Neutral ApartmentNA),(ThreadingModel=Neutral一个特殊的套间,没有任何指定的线程。当STA或MTA线程调用同一进程的NA对象,则调用线程临时离开它的套间并执行COM对象的代码,没有任何线程切换。即任何线程都可以直接了当调用COM对象的方法。[17]因此NA可以认为是优化套间之间方法调用的效率。

    参考:
    https://zh.wikipedia.org/wiki/组件对象模型#线程化与“套间”
    https://docs.microsoft.com/zh-CN/dotnet/api/system.stathreadattribute
    https://stackoverflow.com/questions/1293402/why-does-wpf-require-a-stathread-attribute-to-be-applied-to-the-main-method


    改天接着聊,欢迎来评论区留言互动哈~

    展开全文
  • Windows Presentation Foundation (WPF) 项目中不支持XXX 看了半天没发现问题在哪 项目引用和类都没有问题 最后删除项目的obj文件夹然后重新编译生成,随后关闭项目重新打开项目后发现正常了。 猜测可能是由于...

    今天拷贝项目后出现xaml一堆报错 

    Windows Presentation Foundation (WPF) 项目中不支持XXX

    看了半天没发现问题在哪 项目引用和类都没有问题

    最后删除项目的obj文件夹然后重新编译生成,随后关闭项目重新打开项目后发现正常了。

    猜测可能是由于拷贝项目后有些临时文件路径矛盾引起。

    展开全文
  • C++/CLI 下创建WPF项目的方法 由于WPF不仅仅支持C#/VB开发,还支持其他语言,比如: C++、F#等开发,于是大白我最近花了点时间摸索了一下,本文主要介绍 C++/CLI 下创建WPF项目的方法。 我使用的开发环境是: Win10 x...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 37,515
精华内容 15,006
关键字:

wpf项目