我有一个文本框,其Text属性具有TwoWay MultiBinding,UpdateSourceTrigger设置为PropertyChanged.第一个Binding是一个依赖属性(Value),它有一个PropertyChangedCallBack函数,可以将值四舍五入到一个小数位.
文本框的目的是在用户键入时执行舍入,而不是在文本框失去焦点时执行舍入,因此将UpdateSourceTrigger设置为PropertyChanged.
我遇到的问题是,如果输入的文本不会导致值更改,则Text属性和Value将变得不同步.仅当舍入操作导致值更改时,文本才会动态更新.例如,如果Text和Value都是123.4并且用户在此之后键入1,则Value将四舍五入为相同的值(123.4),但Text显示为123.41.但是,如果在4之后键入9,则值向上舍入为123.5.由于这个实际的变化,文本然后更新为相同(123.5).
是否有任何方法强制文本框从其源更新,即使源自上次触发后没有更改?我尝试过使用BindingExpressionBase.UpdateTarget()但这仅在UpdateSourceTrigger设置为Explicit时有效,不能用作在可以调用UpdateTarget的合适时间之前不再更新的值(例如TextInput处理程序).我已经尝试过其他方法,例如从绑定值显式更新Text值,暂时强制实际更改为Value以调用更新,但这些"hacks"要么不起作用,要么导致其他问题.
任何帮助将不胜感激.
代码如下.
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{local:NumberFormatConverter}"
UpdateSourceTrigger="Explicit"
Mode="TwoWay">
<Binding Path="Value"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
Mode="TwoWay" />
</MultiBinding> …Run Code Online (Sandbox Code Playgroud) binding textbox updatesourcetrigger propertychanged multibinding
我试图将表中的TIMESTAMP字段转换为字符串,以便它可以作为动态SQL的一部分打印或执行.SSMS能够做到这一点,因此必须有一个内置的方法来做到这一点.但是,我无法使用T-SQL工作.
以下正确显示表结果:
SELECT TOP 1 RowVersion FROM MyTable
Run Code Online (Sandbox Code Playgroud)
它表明0x00000000288D17AE.但是,我需要将结果作为更大字符串的一部分.
DECLARE @res VARCHAR(MAX) = (SELECT TOP 1 'test' + CONVERT(BINARY(8), RowVersion) FROM MyTable)
PRINT(@res)
Run Code Online (Sandbox Code Playgroud)
这会产生错误: The data types varchar and binary are incompatible in the add operator
DECLARE @res VARCHAR(MAX) = (SELECT TOP 1 'test' + CONVERT(VARCHAR(MAX), RowVersion) FROM MyTable)
PRINT(@res)
Run Code Online (Sandbox Code Playgroud)
这导致垃圾字符: test (®
实际上,空格只是空字符并终止字符串以便运行动态SQL EXEC().
DECLARE @sql VARCHAR(MAX) = 'SELECT TOP 1 ''test'' + CONVERT(VARCHAR(MAX), RowVersion) FROM MyTable'
EXEC (@sql)
Run Code Online (Sandbox Code Playgroud)
这只显示一个带有"test"一词的表格结果.动态SQL中"test"之后的所有内容都被截断,因为该CONVERT函数首先返回终止空字符.
显然,我想要的结果字符串是"test0x000000000000288D17AE"甚至是十进制等值,在这种情况下将是"test680335278".
任何想法将不胜感激.
我的问题与这个关于使用IEnumerable<T>vs的问题有关IReadOnlyCollection<T>.
我也经常习惯IEnumerable<T>将集合作为返回类型和参数公开,因为它既可以是不可变的,也可以是懒惰的.
但是,我越来越关注代码中地点的扩散,我必须枚举一个参数以避免ReSharper给出的可能的多个枚举警告.我理解为什么ReSharper建议这一点,我同意它建议的代码(下面)以确保封装(即,没有关于调用者的假设).
Foo[] arr = col as Foo[] ?? col.ToArray();
Run Code Online (Sandbox Code Playgroud)
但是,我发现此代码的重复性是污染性的,我同意一些IReadOnlyCollection<T>更好的替代方案,特别是本文中提出的观点,其中指出:
最近,我一直在考虑回归的优点和缺点
IEnumerable<T>.从积极的一面,它大约是最小的一个接口获得,所以给人们留下你的方法作者比承诺更重的替代需要更多的灵活性
IList<T>或(但愿)阵列.但是,正如我在上一篇文章中所概述的那样,
IEnumerable<T>回归诱使来电者违反Liskov替代原则.这太容易让他们使用LINQ扩展方法,如Last()和Count(),其语义IEnumerable<T>不答应.我们需要的是一种更好的方法来锁定一个返回的集合,而不会让这种诱惑如此突出.(我想起Barney Fife艰难地学习这一课.)
IReadOnlyCollection<T>在.NET 4.5中输入new.它只添加一个属性IEnumerable<T>:Count属性.通过承诺计数,你向你的来电者保证你IEnumerable<T>确实有一个终点.然后,他们可以使用LINQ扩展方法,如Last()清醒的良心.
但是,正如观察者可能已经注意到的那样,本文仅讨论使用IReadOnlyCollection<T>返回类型.我的问题是,相同的论点同样适用于将其用于参数吗?对此的任何理论思考或评论也将受到赞赏.
事实上,我认为使用的一般经验法则IReadOnlyCollection<T>是,如果使用的话,可能存在多次枚举(相对于ReSharper警告)IEnumerable<T>.否则,请使用IEnumerable<T>.
我正在实施IEquatable<T>,但我很难就可变GetHashCode类的覆盖达成共识。
以下资源都提供了一个实现,GetHashCode如果对象发生更改,则在对象的生命周期内将返回不同的值:
但是,此链接指出GetHashCode不应为可变类型实现,因为如果对象是集合的一部分,则可能会导致不良行为(这也一直是我的理解)。
有趣的是,MSDN 示例实现了GetHashCode仅使用不可变属性,这符合我的理解。但我很困惑为什么其他资源不涵盖这一点。他们真的错了吗?
如果一个类型根本没有不可变属性,编译器会GetHashCode在我重写时警告该类型丢失Equals(object)。在这种情况下,我应该实现它并只调用base.GetHashCode()或禁用编译器警告,还是我错过了某些内容并且GetHashCode应该始终被覆盖和实现?事实上,如果建议不GetHashCode应该为可变类型实现,为什么还要为不可变类型实现呢?与默认实现相比,它只是为了减少冲突GetHashCode,还是实际上添加了更多有形的功能?
总结我的问题,我的困境是,GetHashCode在可变对象上使用意味着如果对象的属性发生变化,它可以在对象的生命周期内返回不同的值。但不使用它意味着比较可能等效的对象的好处会丢失,因为它将始终返回唯一值,因此集合将始终回退到使用Equals其操作。
输入此问题后,“类似问题”框中弹出了另一个问题,似乎涉及同一主题。答案似乎非常明确,因为在GetHashCode实现中只应使用不可变属性。如果没有,那就干脆不写。Dictionary<TKey, TValue>尽管不是 O(1) 性能,但仍然可以正常运行。
有没有办法访问属性中附加属性的类和属性名称?
例如
public class User {
public string Email { get; set; }
public string FirstName { get; set; }
[MyAttribute]
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后在MyAttribute类中
public class MyAttributeAttribute {
public MyAttributeAttribute () : base() {
string className = /*GET CLASS NAME - should return "User" */
string propertyName = /*GET PROPERTY NAME - should return LastName*/
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以在构造函数中传递信息,但是希望有一种简单的方法可以通过反射或者反复来节省一遍又一遍的重新输入信息.
我有一个Visual Studio解决方案,其中包含许多基于NUnit的C#单元测试项目.我们的TeamCity环境选择要运行的特定单元测试DLL.但是,当使用ReSharper在本地解决方案中运行单元测试时,它会运行所有内容.有没有办法忽略整个项目而不必将Ignore属性放在每个测试夹具上?
我正在BigInteger使用以下命令将 a 序列化为 JSON System.Text.Json:
JsonSerializer.Serialize(new {foo = new BigInteger(ulong.MaxValue) + 1})
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
{"foo":{"IsPowerOfTwo":true,"IsZero":false,"IsOne":false,"IsEven":true,"Sign":1}}
Run Code Online (Sandbox Code Playgroud)
如果我添加一个将值转换BigInteger为 a 的转换器ulong,它当然会失败,因为该BigInteger值太大:
var options = new JsonSerializerOptions();
options.Converters.Add(new BigIntegerConverter());
JsonSerializer.Serialize(new {foo = new BigInteger(ulong.MaxValue) + 1}, options);
Run Code Online (Sandbox Code Playgroud)
这是转换器:
public class BigIntegerConverter : JsonConverter<BigInteger>
{
public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException();
public override void Write(Utf8JsonWriter writer, BigInteger value, JsonSerializerOptions options) => writer.WriteNumberValue((ulong)value);
}
Run Code Online (Sandbox Code Playgroud)
我想要的输出是:
{"foo":18446744073709551616}
Run Code Online (Sandbox Code Playgroud)
我知道这可以通过JsonWriter.WriteRawValueJson.NET 来实现,但我仅限于使用 …
c# biginteger json-serialization jsonconverter system.text.json
继我之前的问题,我设法在Oracle论坛的帮助下回答了自己,我现在有另一个问题,从前一个问题开始(提供给后台).
我希望直接从我的C#代码查询LDAP,以执行Oracle TNS主机名的LDAP查找,以获取连接字符串.这通常存储在tnsnames.ora中,我的组织使用LDAP(通过ldap.ora)使用Active Directory从LDAP服务器解析主机名.
但是,我在我的C#应用程序中使用ODP.NET,托管驱动程序测试版(Oracle.ManagedDataAccess.dll),它不支持LDAP,如前面提到的Oracle论坛回复所指出的发行说明中所述.这就是我希望直接从C#查询LDAP的原因.
我在这里找到了一种方法,使用DirectoryEntry和DirectorySearcher,但我不知道要把什么作为参数DirectorySearcher.我可以访问ldap.ora,其格式如下:
#LDAP.ORA配置
#由Oracle配置工具生成.
DEFAULT_ADMIN_CONTEXT ="dc = xx,dc = mycompany,dc = com"
DIRECTORY_SERVERS =(ldap_server1.mycompany.com:389:636,ldap_server2.mycompany.com:389:636, ...)DIRECTORY_SERVER_TYPE = OID
但是,如何将其映射到在我的C#代码中设置LDAP查询?
在 Windows Server 2019 代理上运行的 Azure DevOps Server(版本 2019.0.1)中,为 NuGet 推送任务选择“允许跳过重复项”选项时,会显示警告:
“允许跳过重复项”选项当前仅在 Azure Pipelines 上可用。如果 NuGet.exe 遇到冲突,任务将失败。
该任务会导致以下错误,导致任务失败,表明上述警告适用:
响应状态代码不表示成功:409(冲突 - 源已包含“MyPackage XYZ”。(DevOps 活动 ID:1A57312F-3C56-4E4D-9E78-73C7072A288F))。
我想知道这个问题是否是 Azure DevOps Server(而不是 Azure DevOps Services)特有的,或者我是否做错了什么,或者是否有其他解决方法。我注意到其他人在另一个问题的评论中也有同样的问题,其中提到在有人询问如何忽略错误 409(重复包)后该选项可用。
我想使用 NuGet 任务忽略重复的包,最好使用 Azure DevOps Server 上的“允许跳过重复项”选项。我知道可以使用脚本来解决这个问题,但如果可能的话我宁愿避免这种情况。任何帮助表示赞赏。
我有一个ASP.NET Web服务,需要发布另一个服务的异步处理请求(单独的进程).因此,该要求是一个持久的队列.服务器是运行SQL Server的Windows Server.
我考虑使用数据库中的表来编写自己的排队服务,其中发布请求,并通知另一个服务然后处理新行.如果服务失败,则在启动时,它会处理队列表中的所有未处理项.
然后,我考虑不使用数据库来维护队列并在ASP.NET应用程序中管理进程中的队列.对于持久性,所有作业都将写入数据库,以便在发生故障时进行检索.
但是,此选项可能不合适,因为我们的想法是使用通用排队服务来处理来自任何服务器应用程序的作业.
所以我接着开始了一个发现之旅,从如何通知我的监听服务在数据库中插入一行.我在SQL Server中阅读了有关查询通知的内容,这使我进入了有关规划通知的页面.在那里,我了解了Windows Service AppFabric,它包含了持久化工作流程的能力.我不确定这是否与此相关,但后来我开始阅读有关Azure AppFabric和Service Bus的信息,这两者都是排队消息的理想选择(尽管Azure不是一个选项,因为我们的服务器出于合规性原因不得将数据发送到环境之外).
最后,我了解到微软将不再支持2017年的AppFabric(因此不再是我的选择),Redis将成为首选武器.
然后,在与上述同事讨论之后,MSMQ(或类似的排队软件)被认为可能是最佳选择,因为它可以让我们更多地控制.
因此,根据我的要求和前面提到的发现之旅,我们非常感谢任何关于什么是好的策略或者考虑好的解决方案的建议.
c# ×7
resharper ×2
sql-server ×2
.net-4.5 ×1
appfabric ×1
asp.net ×1
azure-devops ×1
biginteger ×1
binding ×1
gethashcode ×1
ienumerable ×1
iequatable ×1
immutability ×1
ldap ×1
multibinding ×1
mutable ×1
nuget ×1
nunit ×1
nvarchar ×1
oracle ×1
reflection ×1
ssms ×1
t-sql ×1
textbox ×1
tnsnames ×1
unit-testing ×1