小编And*_*ens的帖子

json.net:如何反序列化动态加载的程序集中的类型?

我正在使用动态加载程序集Assembly.LoadFrom(),然后使用它来实例化它的一些类型.CreateInstance().接下来,我将这些对象放入一个数组中,并使用json.net(配置为TypeNameHandling.Auto)将其序列化为一个文件.在文件中,我可以看到它存储了正确的类型名称,例如: -

"Features": [{
    "$type": "FeaturesAssembly.SomeFeature, FeaturesAssembly",
    // Other serialized properties
}]
Run Code Online (Sandbox Code Playgroud)

问题是我无法反序列化文件.Json.net抛出一个JsonSerializationException,消息"无法加载程序集'FeatureAssembly'",尽管已经动态加载了必要的程序集.我错过了什么?

json.net

3
推荐指数
1
解决办法
1524
查看次数

如何在 .Net Core 中引用 System.Windows 命名空间?

我是 WPF (.Net Framework) 开发人员很长时间了,我终于第一次涉足 .Net Core。我目前正在尝试将一个小型 v4.7.2 WPF 应用程序转换为 .Net Core 3.1。该解决方案包含一个 WPF 应用程序项目和一个类库项目,每个项目只有少数几个类,因此我决定创建一个包含 WPF 应用程序和类库项目(均为 .Net Core 3.1)的新解决方案会更容易,然后从原始解决方案中复制 cs 和 xaml 文件。然而,我似乎在第一个障碍...

许多类使用类型从System.Windows命名空间(和System.Windows.MediaSystem.Windows.Controls等)。这些在 WPF 应用程序项目中解决得很好,但在类库中解决不了。我注意到 WPF 应用程序项目引用了框架“Microsoft.WindowsDesktop.App.Wpf”,但类库项目没有,我认为这是我的问题。但是,我终生无法弄清楚如何将此框架添加到项目中。我该怎么做?!

我在其他地方看到了添加<UseWPF>true</UseWPF>到类 lib csproj 文件的解决方案,但这没有效果。

wpf .net-core wpf-core

3
推荐指数
1
解决办法
648
查看次数

Content属性上的WPF触发器(绑定到布尔值)不起作用

我有一个按钮控件,其Content属性绑定到我的viewmodel上的布尔属性.该按钮用于打开和关闭工业机器上的阀门,通过异步WCF调用执行.当服务返回时,它会更新boolean属性,进而触发对按钮的可视状态的更改.这是按钮xaml:

<Button Command="{Binding Path=OpenCloseValveCommand}"
        Content="{Binding Path=ValveIsOpen}"
        Style="{StaticResource ResourceKey=OnOffButtonStyle}">
Run Code Online (Sandbox Code Playgroud)

当阀门打开时,按钮需要为绿色,当阀门关闭时,按钮需要穿过它.这是样式xaml:

<Style TargetType="Button" x:Key="OnOffButtonStyle" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Canvas>
                    <Rectangle x:Name="_rect" Fill="Red" Stroke="Black" Width="30" Height="30"></Rectangle>
                    <Path x:Name="_path" Data="M0,0 L30,30 M0,30 L30,0" StrokeThickness="1" Stroke="Black" />
                </Canvas>
                <ControlTemplate.Triggers>
                    <Trigger Property="Content" Value="true">
                        <Setter TargetName="_rect" Property="Fill" Value="Lime" />
                        <Setter TargetName="_path" Property="Visibility" Value="Hidden" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

不幸的是,触发器似乎没有触发.我猜这与按钮内容绑定到布尔类型有关 - 我是否需要使用"true"之外的其他内容作为触发值?(如果我将viewmodel属性更改为整数并使用0或1,并且触发值为"1",则触发器有效.

提前致谢

安迪

wpf binding

2
推荐指数
1
解决办法
6605
查看次数

在 WPF 用户控件库中指定样式

我在不同项目之间共享通用样式时遇到了一些问题。这是我的项目:-

  • “Common” - 包含常见 WPF 样式的类库。
  • “插件” - 包含用户控件(不是自定义控件)的类库。
  • “核心应用程序”——核心 WPF 应用程序,显示“插件”中定义的用户控件。

“Common”和“Core app”位于同一个解决方案中,而“Plugin”则位于自己的解决方案中。

“核心应用程序”项目中的样式工作正常 - 它引用“通用”项目并在 App.xaml 中包含以下内容:-

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/Common;component/MyStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
Run Code Online (Sandbox Code Playgroud)

在“核心应用程序”项目中编辑 XAML 文件时,我对样式名称进行了智能感知,没有波浪线下划线,并且在运行时一切正常。

问题出在“插件”项目上。我引用了“Common”程序集,并创建了一个 \Themes\Generic.xaml 文件,其中包含与上述相同的合并 XAML。Generic.xaml 具有“Page”的构建操作,我已将以下内容添加到 AssemblyInfo.cs:-

[assembly: ThemeInfo(ResourceDictionaryLocation.None, 
                     ResourceDictionaryLocation.SourceAssembly)]
Run Code Online (Sandbox Code Playgroud)

当我在这个“插件”项目中编辑用户控件的 XAML 时,“通用”程序集中的样式不会显示在智能感知中,并且 VS/Resharper 在它们的名称下放置了一条波浪线。我什至直接在 Generic.xaml 中添加了一个样式,但是 UC 也看不到。用户控件看起来像这样:-

<UserControl ..blah..>
    <StackPanel>
        <TextBlock Style="{StaticResource AStyleInCommonAssembly}" Text="Hello"/>
        <TextBlock Style="{StaticResource AStyleInGenericXaml}" Text="World"/>
    </StackPanel>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

在运行时,WPF确实正确应用了驻留在“通用”程序集中的样式(我猜它是由于 App.xaml 中的字典合并而找到它们的)。但是它仍然无法找到我直接添加到 Generic.xaml 的样式。

我错过了什么?这种方法是否仅适用于自定义控件,而不适用于我正在处理的用户控件?我的首要任务是让事情在运行时工作,但获得设计时/智能感知体验将是一个奖励。

wpf

2
推荐指数
1
解决办法
2660
查看次数

温莎城堡 - 如何通过名称解析?

我的应用程序使用“SignalR”客户端/服务器通信框架。如果您不熟悉,服务器端应用程序通常包含一个或多个“中心”类(类似于 asmx Web 服务),每个类都提供可由客户端调用的方法。在启动过程中,客户端需要首先创建连接,然后为需要与之通信的每个集线器创建一个“代理”,例如:-

var hubConnection = new HubConnection("http://...");
var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
var barHubProxy = hubConnection.CreateHubProxy("BarHub");
...etc...
Run Code Online (Sandbox Code Playgroud)

传递给的字符串参数CreateHubProxy()是服务器端集线器类的名称。方法返回类型为IHubProxy.

感觉我应该能够在这里利用温莎,但我正在努力寻找解决方案。我的第一个想法是实例化集线器代理并向 Windsor 注册这些实例(按名称),例如

var fooHubProxy = hubConnection.CreateHubProxy("FooHub");
container.Register(Component.For<IHubProxy>().Instance(fooHubProxy).LifestyleSingleton().Named("FooHub"));
...etc...
Run Code Online (Sandbox Code Playgroud)

问题是,当一个类需要中心代理时,通过名称解析它的唯一方法是使用服务定位器模式,但不建议这样做。还有哪些其他 Windsor 功能(例如类型化工厂等)在这里可能有用?

编辑

我刚刚找到 Windsor's .UsingFactoryMethod,想知道这是否可行,以简化集线器注册:

container.Register(Component.For<IHubProxy>()
                   .UsingFactoryMethod((kernel, context) => hubConnection.CreateHubProxy("FooHub"))
                   .LifestyleSingleton()
                   .Named("FooHub"));
Run Code Online (Sandbox Code Playgroud)

我想我仍然有如何通过名称解决的问题。

castle-windsor

2
推荐指数
1
解决办法
6231
查看次数

在什么情况下ICommand CanExecute可能不会更新?

多年来,我一直在几个大型项目中使用Josh Smith的RelayCommand实现.但是今天我遇到了一个场景,其中我的一个命令上的CanExecute没有刷新.我不知道是什么造成了它 - 视图模型没有做任何我已经做过几十次的事情.

VM的构造函数创建了几个命令.第一个是"开始"命令: -

StartCommand = new RelayCommand(o => StartAsync(), o => true);
Run Code Online (Sandbox Code Playgroud)

StartAsync()方法如下所示: -

private async void StartAsync()
{
    IsRunning = true;
    await Task.Run(() => SomeLongRunningProcess(); }
    IsRunning = false;
}
Run Code Online (Sandbox Code Playgroud)

还有一个"保存"命令: -

SaveCommand = new RelayCommand(o => Save(), o => !IsRunning);
Run Code Online (Sandbox Code Playgroud)

('IsRunning'是一个bog标准属性,实现了INotifyPropertyChanged.除了用于"CanExecute"委托之外,它还绑定到视图中几个控件的IsEnabled属性以启用/禁用它们).

当我单击"开始"按钮(绑定到"StartCommand")时,"保存"按钮被正确禁用.b/g进程运行完成,然后将IsRunning设置为false,但这不会触发"保存"按钮以启用.它只有在我点击视图的某个位置时才会启用.

(其控件IsEnabled属性绑定到虚拟机IsRunning性能能够正确地禁用,顺便说一句).

我有一些关于这个的SO文章,但没有真正解释为什么会发生这种情况.我的解决方法是将按钮的IsEnabled属性绑定到'IsRunning',但令人沮丧的是这个特定视图拒绝播放.关于可能导致这种情况的任何想法?常识说它是特定于这个视图/ VM的东西,但我很难过(我不打算在这里发布代码 - 它有太多了).

wpf

2
推荐指数
1
解决办法
575
查看次数

单击静态文本的事件

我有一个名为IDC_STATIC的静态文本,我为其创建了一个click事件,但是当它被单击时它没有被调用.

ON_BN_CLICKED(IDC_STATIC, ontest)  //(begin message map)
void test::ontest(my method)
{
  MessageBox("success");
}
afx_msg void test();  //(header file)
Run Code Online (Sandbox Code Playgroud)

代码有什么问题?

mfc visual-c++

1
推荐指数
1
解决办法
4641
查看次数

SignalR .Net客户端 - 如何同步和异步调用

我正在使用.Net客户端(而不是javascript)学习SignalR,并希望澄清如何以同步或异步方式调用集线器代理方法.

没有返回值的方法

到目前为止,我一直在做这样的事情: -

myHubProxy.Invoke("DoSomething");
Run Code Online (Sandbox Code Playgroud)

我发现这是异步的,这很好,因为它实际上是"一劳永逸",并且不需要等待返回值.但有几个问题: -

  1. 在try..catch块中包装Invoke是否有任何影响,特别是它是异步的?我可能想知道呼叫是否失败.
  2. 是否有任何情况需要调用不同步返回值的方法?我已经看到了提到的.Wait()方法,但我想不出你为什么要这样做.

返回值的方法

到目前为止,我一直在使用该Result物业,例如: -

var returnValue = myHubProxy.Invoke<string>("DoSomething").Result;
Console.WriteLine(returnValue);
Run Code Online (Sandbox Code Playgroud)

我假设它同步工作 - 毕竟,在返回结果之前,它无法进入下一行.但是我如何异步调用这样的方法呢?是否有可能指定一个回调方法,或者我现在应该真的使用async/await(这是我承认还没有学到的东西)?

signalr signalr.client

1
推荐指数
1
解决办法
7985
查看次数

SignalR服务器内存消耗(归咎于Windsor IHubActivator?)

我正在测试一个SignalR服务器(在控制台应用程序中自托管),它最终将构成数据记录系统的基础.测试客户端正在向集线器发出大约180个呼叫/秒,而消息本身非常小(只是一个名称/值对).

我正在使用Castle Windsor进行DI,使用自定义IHubActivator来解析Hub实例:

internal class WindsorHubActivator : IHubActivator
{
    private readonly IWindsorContainer _container;

    public WindsorHubActivator(IWindsorContainer container)
    {
        _container = container;
    }

    public IHub Create(HubDescriptor descriptor)
    {
        var hubType = descriptor.HubType;
        return _container.Resolve(hubType) as IHub;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是集线器类:

public class TelemetryHub : Hub
{
    private readonly TelemetryDataService _telemetryDataService;

    public TelemetryHub(TelemetryDataService telemetryDataService)
    {
        _telemetryDataService = telemetryDataService;
    }

    public void LogTelemetryData(string name, double value)
    {
        _telemetryDataService.LogTelemetryData(name, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

当集线器类在Windsor注册为"瞬态"时,内存消耗量稳步攀升,直到达到2Gb然后因OOM异常而下降.如果我将Hub注册为"Singleton",那么应用程序内存消耗将保持非常低且一致.

TelemetryDataService班是不是问题.我已经注释掉了hub的构造函数和方法代码,问题仍然存在.

出于好奇,我接着进一步改变了阶段,改变了WindsorHubActivator阶级,将温莎带出了等式:

internal class WindsorHubActivator : IHubActivator …
Run Code Online (Sandbox Code Playgroud)

c# castle-windsor signalr signalr-hub

1
推荐指数
1
解决办法
834
查看次数

从属性设置器调用异步方法

我有几个地方可以做到这一点,但重做代码是不可行/切实可行的.然而,似乎该方法可以被称为"正常",例如: -

set
{
    ...
    DoSomethingAsync();
}
Run Code Online (Sandbox Code Playgroud)

在此行下的VS编辑器中出现一个波形,此工具提示警告: -

因为不等待该调用,所以在调用完成之前继续执行当前方法.

没有async/await关键字,我有点期望该方法最终会被同步调用.我没有到这里来的是什么?

如果我将线条更改为以下内容,则波形/警告消失: -

DoSomethingAsync().Wait();
Run Code Online (Sandbox Code Playgroud)

据推测,这会把它变成一个阻塞的电话?

纯粹出于好奇,做以下事情会产生什么影响: -

Task.Run(() => DoSomethingAsync());
Run Code Online (Sandbox Code Playgroud)

c# asynchronous async-await

1
推荐指数
2
解决办法
2188
查看次数

将基于委托回调的 API 转换为异步 API

我必须使用一个 API 如下所示的库:

public void Connect();

...

public delegate void ConnectResultDelegate(bool succeeded, string msg);
public ConnectResultDelegate ConnectResultHandler;
Run Code Online (Sandbox Code Playgroud)

调用该Connect()方法后,ConnectResultHandler将调用回调委托。

API 公开了以类似“请求-响应”方式工作的其他方法;我猜委托的原因是这些方法与外部硬件设备交互,并且响应(委托调用)可能在很多毫秒内不会发生。

我希望我能以某种方式包装 API,让我能够以更“顺序”的方式使用它,更像是 async/await,大致如下:

void DoSomething()
{
    _library.Connect();
    // Wait for notification that this has completed
    // Do something with the response passed to the delegate callback

    _library.Configure(...);
    // Wait for notification that this has completed
    // Do something with the response
    ..etc..
}
Run Code Online (Sandbox Code Playgroud)

想法?重构库本身不是一个选择。

那里有一两个类似的 SO 问题,但它们的不同之处在于它们的委托被传递给方法,而不是单独的属性,这使得包装在任务中相对容易。

c# task-parallel-library async-await

1
推荐指数
1
解决办法
1518
查看次数

当所选单元格驻留在该行中时,为 WPF DataGrid 行标题设置样式?

我有一个 WPF DataGrid 配置为只允许选择单个单元格,即:-

SelectionMode="Single"
SelectionUnit="Cell"
Run Code Online (Sandbox Code Playgroud)

我想要做的是更改包含当前选定单元格的任何行的行标题的背景。到目前为止,我想出了以下内容,但它不起作用。

这是 XAML 样式,它将背景属性绑定到多值转换器。转换器绑定到标头DataGridRow 以下SelectedCells属性DataGrid:-

<Style TargetType="{x:Type DataGridRowHeader}">
    <Setter Property="Background">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource dataGridHeaderBackgroundConverter}" Mode="OneWay">
                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" />
                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}" 
                         Path="SelectedCells"
                         Mode="OneWay"/>
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

多转换器的Convert方法看起来像这样(我已经删除了空检查代码以保持简洁):-

var row = values[0] as DataGridRow;
var selectedCells = values[1] as IList<DataGridCellInfo>;
var selectedCell = selectedCells[0];

return selectedCell.Item == row.Item ? Colors.Red : Colors.LightGray;
Run Code Online (Sandbox Code Playgroud)

该方法似乎只在 DataGrid 最初呈现时(没有选择时)才会被调用。选择单元格后它不会被调用,那么我错过了什么?

wpf xaml wpfdatagrid

0
推荐指数
1
解决办法
4354
查看次数