wpf 相关问题

Windows Presentation Foundation或WPF是用于在基于Windows的应用程序中呈现用户界面的子系统。

从ViewModel调用View的CodeBehind中的方法?

我的视图背后的代码中有一个方法(这个方法对我的用户界面做了一些事情)。 不管怎样,我想从我的 ViewModel 触发这个方法。这怎么能做到呢?

回答 7 投票 0

WPF - 如何将 DrawingImage 放置在图像内?

我想在 Image 对象上绘制一个矩形,并在每边留下 10 的边框。然而,它总是将矩形推入图像的左上角。 这是代码: ...

回答 1 投票 0

将颜色名称转换为 SolidColorBrush

如何将颜色名称转换为 SolidColorBrush 类型?我的意思是这个词,即“黄色”。 SolidColorBrush scb = ??? ; // “黄色的” 谢谢!

回答 5 投票 0

WPF 中处理 UI 异常的最有效方法

我正在创建一个WPF应用程序,我对MVVM架构很陌生,有人可以向我解释一下当一条数据与条件不匹配时如何在我的UI上简单地显示一条警报消息,其他...

回答 1 投票 0

在WPF中,如何为每个可展开的树视图节点添加一个按钮?

节点可以展开或折叠。在这两种情况下都需要显示按钮。 像这样的东西: ├─ 第1项 ├─ 第2项 │ ├─ 第2-1项 │ ├─ 第2-2项 ├─ 第3项 │ ├─ 第3-1项... 节点可以展开或折叠。在这两种情况下都需要显示按钮。 像这样的东西: ├─ item1 ├─ item2 <button> │ ├─ item2-1 │ ├─ item2-2 ├─ item3 <button> │ ├─ item3-1 │ ├─ item3-2 ├─ item4 ├─ item5 最好在 XAML 中执行此操作。 感谢您的想法。 为此,您需要首先复制树视图项的源 XAML,可以在此处找到该源 XAML。 然后您可以分析代码并查看使用 HasItems 属性来调整控件视觉的部分。从那里开始,您将看到一个名为 PART_Header 的控件,由触发器处理: <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="HasHeader" Value="false" /> <Condition Property="Width" Value="Auto" /> </MultiTrigger.Conditions> <Setter TargetName="PART_Header" Property="MinWidth" Value="75" /> </MultiTrigger> <StackPanel Orientation="Horizontal"> <ContentPresenter x:Name="PART_Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" ContentSource="Header" /> <Button x:Name="PART_Header_Button" Content="Expand" /> </StackPanel>

回答 1 投票 0

来自 XAML 中只读属性的 OneWayToSource 绑定

我正在尝试以 OneWayToSource 作为模式绑定到 Readonly 属性,但这似乎无法在 XAML 中完成: 我正在尝试以 Readonly 作为模式绑定到 OneWayToSource 属性,但似乎无法在 XAML 中完成: <controls:FlagThingy IsModified="{Binding FlagIsModified, ElementName=container, Mode=OneWayToSource}" /> 我得到: 无法设置属性“FlagThingy.IsModified”,因为它没有可访问的设置访问器。 IsModified 是 DependencyProperty 上的只读 FlagThingy。我想将该值绑定到容器上的 FlagIsModified 属性。 需要明确的是: FlagThingy.IsModified --> container.FlagIsModified ------ READONLY ----- ----- READWRITE -------- 仅使用 XAML 可以吗? 更新:好吧,我通过在容器上设置绑定而不是在FlagThingy上修复了这种情况。但我还是想知道这是否可能。 OneWayToSource 的一些研究成果... 选项#1。 // Control definition public partial class FlagThingy : UserControl { public static readonly DependencyProperty IsModifiedProperty = DependencyProperty.Register("IsModified", typeof(bool), typeof(FlagThingy), new PropertyMetadata()); } <controls:FlagThingy x:Name="_flagThingy" /> // Binding Code Binding binding = new Binding(); binding.Path = new PropertyPath("FlagIsModified"); binding.ElementName = "container"; binding.Mode = BindingMode.OneWayToSource; _flagThingy.SetBinding(FlagThingy.IsModifiedProperty, binding); 选项#2 // Control definition public partial class FlagThingy : UserControl { public static readonly DependencyProperty IsModifiedProperty = DependencyProperty.Register("IsModified", typeof(bool), typeof(FlagThingy), new PropertyMetadata()); public bool IsModified { get { return (bool)GetValue(IsModifiedProperty); } set { throw new Exception("An attempt ot modify Read-Only property"); } } } <controls:FlagThingy IsModified="{Binding Path=FlagIsModified, ElementName=container, Mode=OneWayToSource}" /> 选项#3(真正的只读依赖属性) System.ArgumentException:“IsModified”属性无法进行数据绑定。 // Control definition public partial class FlagThingy : UserControl { private static readonly DependencyPropertyKey IsModifiedKey = DependencyProperty.RegisterReadOnly("IsModified", typeof(bool), typeof(FlagThingy), new PropertyMetadata()); public static readonly DependencyProperty IsModifiedProperty = IsModifiedKey.DependencyProperty; } <controls:FlagThingy x:Name="_flagThingy" /> // Binding Code Same binding code... Reflector给出答案: internal static BindingExpression CreateBindingExpression(DependencyObject d, DependencyProperty dp, Binding binding, BindingExpressionBase parent) { FrameworkPropertyMetadata fwMetaData = dp.GetMetadata(d.DependencyObjectType) as FrameworkPropertyMetadata; if (((fwMetaData != null) && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly) { throw new ArgumentException(System.Windows.SR.Get(System.Windows.SRID.PropertyNotBindable, new object[] { dp.Name }), "dp"); } .... 这是 WPF 的限制,是设计使然。 Connect 上有报道: 来自只读依赖属性的 OneWayToSource 绑定 我制定了一个解决方案,可以动态地将只读依赖属性推送到名为 PushBinding 的源,我在 博客中提到了这里。下面的示例将 OneWayToSource 从只读 DP 的 ActualWidth 和 ActualHeight 绑定到 DataContext 的 Width 和 Height 属性 <TextBlock Name="myTextBlock"> <pb:PushBindingManager.PushBindings> <pb:PushBinding TargetProperty="ActualHeight" Path="Height"/> <pb:PushBinding TargetProperty="ActualWidth" Path="Width"/> </pb:PushBindingManager.PushBindings> </TextBlock> PushBinding 通过使用两个依赖属性(Listener 和 Mirror)来工作。侦听器已绑定 OneWay 到 TargetProperty,并在 PropertyChangedCallback 中更新 Mirror 属性,该属性已绑定 OneWayToSource 到 Binding 中指定的任何内容。 可以在这里下载演示项目。 它包含源代码和简短的示例用法。 写下这个: 用途: <TextBox Text="{Binding Text}" p:OneWayToSource.Bind="{p:Paths From={x:Static Validation.HasErrorProperty}, To=SomeDataContextProperty}" /> 代码: using System; using System.Windows; using System.Windows.Data; using System.Windows.Markup; public static class OneWayToSource { public static readonly DependencyProperty BindProperty = DependencyProperty.RegisterAttached( "Bind", typeof(ProxyBinding), typeof(OneWayToSource), new PropertyMetadata(default(Paths), OnBindChanged)); public static void SetBind(this UIElement element, ProxyBinding value) { element.SetValue(BindProperty, value); } [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)] [AttachedPropertyBrowsableForType(typeof(UIElement))] public static ProxyBinding GetBind(this UIElement element) { return (ProxyBinding)element.GetValue(BindProperty); } private static void OnBindChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ProxyBinding)e.OldValue)?.Dispose(); } public class ProxyBinding : DependencyObject, IDisposable { private static readonly DependencyProperty SourceProxyProperty = DependencyProperty.Register( "SourceProxy", typeof(object), typeof(ProxyBinding), new PropertyMetadata(default(object), OnSourceProxyChanged)); private static readonly DependencyProperty TargetProxyProperty = DependencyProperty.Register( "TargetProxy", typeof(object), typeof(ProxyBinding), new PropertyMetadata(default(object))); public ProxyBinding(DependencyObject source, DependencyProperty sourceProperty, string targetProperty) { var sourceBinding = new Binding { Path = new PropertyPath(sourceProperty), Source = source, Mode = BindingMode.OneWay, }; BindingOperations.SetBinding(this, SourceProxyProperty, sourceBinding); var targetBinding = new Binding() { Path = new PropertyPath($"{nameof(FrameworkElement.DataContext)}.{targetProperty}"), Mode = BindingMode.OneWayToSource, Source = source }; BindingOperations.SetBinding(this, TargetProxyProperty, targetBinding); } public void Dispose() { BindingOperations.ClearAllBindings(this); } private static void OnSourceProxyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { d.SetCurrentValue(TargetProxyProperty, e.NewValue); } } } [MarkupExtensionReturnType(typeof(OneWayToSource.ProxyBinding))] public class Paths : MarkupExtension { public DependencyProperty From { get; set; } public string To { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { var provideValueTarget = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget)); var targetObject = (UIElement)provideValueTarget.TargetObject; return new OneWayToSource.ProxyBinding(targetObject, this.From, this.To); } } 尚未在样式和模板中进行测试,猜测它需要特殊的外壳。 这是另一个基于 SizeObserver 的附加属性解决方案,详细信息请参见此处 将只读 GUI 属性推回 ViewModel public static class MouseObserver { public static readonly DependencyProperty ObserveProperty = DependencyProperty.RegisterAttached( "Observe", typeof(bool), typeof(MouseObserver), new FrameworkPropertyMetadata(OnObserveChanged)); public static readonly DependencyProperty ObservedMouseOverProperty = DependencyProperty.RegisterAttached( "ObservedMouseOver", typeof(bool), typeof(MouseObserver)); public static bool GetObserve(FrameworkElement frameworkElement) { return (bool)frameworkElement.GetValue(ObserveProperty); } public static void SetObserve(FrameworkElement frameworkElement, bool observe) { frameworkElement.SetValue(ObserveProperty, observe); } public static bool GetObservedMouseOver(FrameworkElement frameworkElement) { return (bool)frameworkElement.GetValue(ObservedMouseOverProperty); } public static void SetObservedMouseOver(FrameworkElement frameworkElement, bool observedMouseOver) { frameworkElement.SetValue(ObservedMouseOverProperty, observedMouseOver); } private static void OnObserveChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { var frameworkElement = (FrameworkElement)dependencyObject; if ((bool)e.NewValue) { frameworkElement.MouseEnter += OnFrameworkElementMouseOverChanged; frameworkElement.MouseLeave += OnFrameworkElementMouseOverChanged; UpdateObservedMouseOverForFrameworkElement(frameworkElement); } else { frameworkElement.MouseEnter -= OnFrameworkElementMouseOverChanged; frameworkElement.MouseLeave -= OnFrameworkElementMouseOverChanged; } } private static void OnFrameworkElementMouseOverChanged(object sender, MouseEventArgs e) { UpdateObservedMouseOverForFrameworkElement((FrameworkElement)sender); } private static void UpdateObservedMouseOverForFrameworkElement(FrameworkElement frameworkElement) { frameworkElement.SetCurrentValue(ObservedMouseOverProperty, frameworkElement.IsMouseOver); } } 在控件中声明附加属性 <ListView ItemsSource="{Binding SomeGridItems}" ut:MouseObserver.Observe="True" ut:MouseObserver.ObservedMouseOver="{Binding IsMouseOverGrid, Mode=OneWayToSource}"> 这是绑定到 Validation.HasError 的另一个实现 public static class OneWayToSource { public static readonly DependencyProperty BindingsProperty = DependencyProperty.RegisterAttached( "Bindings", typeof(OneWayToSourceBindings), typeof(OneWayToSource), new PropertyMetadata(default(OneWayToSourceBindings), OnBinidngsChanged)); public static void SetBindings(this FrameworkElement element, OneWayToSourceBindings value) { element.SetValue(BindingsProperty, value); } [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)] [AttachedPropertyBrowsableForType(typeof(FrameworkElement))] public static OneWayToSourceBindings GetBindings(this FrameworkElement element) { return (OneWayToSourceBindings)element.GetValue(BindingsProperty); } private static void OnBinidngsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((OneWayToSourceBindings)e.OldValue)?.ClearValue(OneWayToSourceBindings.ElementProperty); ((OneWayToSourceBindings)e.NewValue)?.SetValue(OneWayToSourceBindings.ElementProperty, d); } } public class OneWayToSourceBindings : FrameworkElement { private static readonly PropertyPath DataContextPath = new PropertyPath(nameof(DataContext)); private static readonly PropertyPath HasErrorPath = new PropertyPath($"({typeof(Validation).Name}.{Validation.HasErrorProperty.Name})"); public static readonly DependencyProperty HasErrorProperty = DependencyProperty.Register( nameof(HasError), typeof(bool), typeof(OneWayToSourceBindings), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); internal static readonly DependencyProperty ElementProperty = DependencyProperty.Register( "Element", typeof(UIElement), typeof(OneWayToSourceBindings), new PropertyMetadata(default(UIElement), OnElementChanged)); private static readonly DependencyProperty HasErrorProxyProperty = DependencyProperty.RegisterAttached( "HasErrorProxy", typeof(bool), typeof(OneWayToSourceBindings), new PropertyMetadata(default(bool), OnHasErrorProxyChanged)); public bool HasError { get { return (bool)this.GetValue(HasErrorProperty); } set { this.SetValue(HasErrorProperty, value); } } private static void OnHasErrorProxyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { d.SetCurrentValue(HasErrorProperty, e.NewValue); } private static void OnElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue == null) { BindingOperations.ClearBinding(d, DataContextProperty); BindingOperations.ClearBinding(d, HasErrorProxyProperty); } else { var dataContextBinding = new Binding { Path = DataContextPath, Mode = BindingMode.OneWay, Source = e.NewValue }; BindingOperations.SetBinding(d, DataContextProperty, dataContextBinding); var hasErrorBinding = new Binding { Path = HasErrorPath, Mode = BindingMode.OneWay, Source = e.NewValue }; BindingOperations.SetBinding(d, HasErrorProxyProperty, hasErrorBinding); } } } xaml 中的用法 <StackPanel> <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"> <local:OneWayToSource.Bindings> <local:OneWayToSourceBindings HasError="{Binding HasError}" /> </local:OneWayToSource.Bindings> </TextBox> <CheckBox IsChecked="{Binding HasError, Mode=OneWay}" /> </StackPanel> 此实现特定于绑定 Validation.HasError WPF 不会使用 CLR 属性设置器,但似乎它会基于它进行一些奇怪的验证。 可能在你的情况下这可能没问题: public bool IsModified { get { return (bool)GetValue(IsModifiedProperty); } set { throw new Exception("An attempt ot modify Read-Only property"); } } 嗯...我不确定我是否同意这些解决方案。如何在属性注册中指定一个忽略外部更改的强制回调?例如,我需要实现一个只读 Position 依赖属性来获取 MediaElement 控件在用户控件内的位置。我是这样做的: public static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(double), typeof(MediaViewer), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, OnPositionChanged, OnPositionCoerce)); private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctrl = d as MediaViewer; } private static object OnPositionCoerce(DependencyObject d, object value) { var ctrl = d as MediaViewer; var position = ctrl.MediaRenderer.Position.TotalSeconds; if (ctrl.MediaRenderer.NaturalDuration.HasTimeSpan == false) return 0d; else return Math.Min(position, ctrl.Duration); } public double Position { get { return (double)GetValue(PositionProperty); } set { SetValue(PositionProperty, value); } } 换句话说,只需忽略更改并返回由不具有 public 修饰符的不同成员支持的值。 -- 在上面的例子中,MediaRenderer实际上是私有的MediaElement控件。 我解决此限制的方法是在类中仅公开 Binding 属性,将 DependencyProperty 完全保持为私有。我实现了一个“PropertyBindingToSource”只写属性(这个属性不是 DependencyProperty),它可以设置为 xaml 中的绑定值。在此只写属性的设置器中,我调用 BindingOperations.SetBinding 将绑定链接到 DependencyProperty。 对于OP的具体示例,它看起来像这样: FlatThingy 实现: public partial class FlatThingy : UserControl { public FlatThingy() { InitializeComponent(); } public Binding IsModifiedBindingToSource { set { if (value?.Mode != BindingMode.OneWayToSource) { throw new InvalidOperationException("IsModifiedBindingToSource must be set to a OneWayToSource binding"); } BindingOperations.SetBinding(this, IsModifiedProperty, value); } } public bool IsModified { get { return (bool)GetValue(IsModifiedProperty); } private set { SetValue(IsModifiedProperty, value); } } private static readonly DependencyProperty IsModifiedProperty = DependencyProperty.Register("IsModified", typeof(bool), typeof(FlatThingy), new PropertyMetadata(false)); private void Button_Click(object sender, RoutedEventArgs e) { IsModified = !IsModified; } } 请注意,静态只读 DependencyProperty 对象是私有的。在控件中,我添加了一个按钮,其单击由 Button_Click 处理。 在我的 window.xaml 中使用 FlatThingy 控件: <Window x:Class="ReadOnlyBinding.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ReadOnlyBinding" mc:Ignorable="d" DataContext="{x:Static local:ViewModel.Instance}" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Text="{Binding FlagIsModified}" Grid.Row="0" /> <local:FlatThingy IsModifiedBindingToSource="{Binding FlagIsModified, Mode=OneWayToSource}" Grid.Row="1" /> </Grid> 请注意,我还实现了一个 ViewModel 用于绑定到此处未显示的视图模型。它公开了一个名为“FlagIsModified”的 DependencyProperty,您可以从上面的源代码中收集到。 它工作得很好,允许我以松散耦合的方式将信息从 View 推回 ViewModel,并明确定义信息流的方向。 您现在的装订方向错误。 每当您正在创建的控件上的 IsModified 发生更改时,OneWayToSource 将尝试更新容器上的 FlagIsModified。 您想要相反的结果,即将 IsModified 绑定到 container.FlagIsModified。 为此,您应该使用绑定模式 OneWay <controls:FlagThingy IsModified="{Binding FlagIsModified, ElementName=container, Mode=OneWay}" /> 枚举成员的完整列表:http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx

回答 9 投票 0

在纯 XAML 中更改父级悬停的图像源

我有一个用户控件,其中包含带有一些元素的边框(StackPanel 中的图像和文本块) 当边框悬停时,是否可以更改纯 XAML 中的图像源? 我可以改变边框

回答 1 投票 0

WPF 应用程序分配大量 TimerQueueTimer 对象

我使用 .NET 8 构建了 WPF 应用程序,在某些时候它的 CPU 和内存突然激增。我设法捕获内存快照,似乎有很多 TimerQueueTimer 对象

回答 1 投票 0

WPF 4 DataGrid:将行号放入 RowHeader

我希望将行号放入 WPF 4 DataGrid 的 RowHeader 中,以便它有一个类似于 Excel 的列用于显示 DataGrid 的行号。 我在网上看到的解决方案建议

回答 6 投票 0

在 WPF 的 TextBox 中使用手机掩码

我有一个包含此文本框的窗口: 正如你所看到的,我是审美干扰镜...

回答 1 投票 0

C# 运行时的 VS Studio ImageBrush TIF 图像文件未显示在表单上

我有一些 C# 代码可以在运行时将不同的图像文件加载到表单的 ImageBrush 背景对象中,但它在运行时不会显示在表单中,仅作为默认文件图像(文件设置...

回答 1 投票 0

WPF:SystemParameters.WindowCaptionButtonHeight 返回的数字小于预期

我们有一个窗口,我们将 WindowChrome GlassFrameThickness 设置为负值,以便玻璃框架延伸到整个窗口。 有了这个,系统参数。

回答 2 投票 0

如何在WPF DataGrid中执行单击复选框选择?

我有一个 DataGrid,第一列作为文本列,第二列作为复选框列。我想要的是,如果我单击复选框。应该检查一下。 但是,需要单击两次才能被选中,对于

回答 13 投票 0

在构建后步骤中调用 Obfuscar

我正在开发一个 C# WPF 项目,我需要一些混淆。我发现了 Obfuscar,它看起来非常有前途,使用 nuget 和构建后事件似乎是一个可靠的解决方案。所以我安装了 nuget

回答 2 投票 0

如果 ItemsControl 出现验证错误则禁用按钮

我有一个 MVVM (Prism) 应用程序。 UserControl 具有以下元素: 我有一个 MVVM (Prism) 应用程序。 UserControl 具有以下元素: <Grid> <ItemsControl x:Name="MyItemsControl" ItemsSource="{Binding Path=OrderCollection}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBox x:Name="MyTextBox"> <TextBox.Text> <Binding Path="ID" Mode="TwoWay"> <Binding.ValidationRules> <vr:OrderIDValidationRule/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Button x:Name="MyButton"> </Button> </Grid> OrderIDValidationRule 只是一个简单的验证规则,用于检查 ID 是否在有效范围内。来自 ViewModel 的代码: public ObservableCollection<Order> OrderCollection; public class Order : BindableBase { private int? _id; public int? ID { get => _id; set => SetProperty(ref _id, value); } } 如果 MyTextBox(带有任何订单)有一些错误的值,有没有办法禁用 MyButton。例如,如果用户输入“abc”。在这种情况下,会显示验证错误,但绑定源不会更新 - 不确定 INotifyDataErrorInfo 是否可以在这里提供帮助 基于我的答案的示例https://stackoverflow.com/a/74293719/13349759 using System; using System.Reflection; using System.Windows; using System.Windows.Data; namespace CommonCore { public static class BindingExpressionHelper { private static readonly Func<BindingExpressionBase, DependencyObject, DependencyProperty, object> GetValueOfBindingExpression; static BindingExpressionHelper() { Type beType = typeof(BindingExpressionBase); var beMethod = beType .GetMethod("GetValue", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, new Type[] { typeof(DependencyObject), typeof(DependencyProperty) }) ?? throw new Exception("GetValue method not found."); var beFunc = (Func<BindingExpressionBase, DependencyObject, DependencyProperty, object>) beMethod.CreateDelegate(typeof(Func<BindingExpressionBase, DependencyObject, DependencyProperty, object>)); GetValueOfBindingExpression = beFunc; } /// <summary>Returns the source value of this binding expression.</summary> /// <param name="bindingExpression">The binding expression whose value to get.</param> /// <returns>The value of the binding expression received.</returns> public static object GetSourceValue(this BindingExpressionBase bindingExpression) { DependencyObject target = bindingExpression.Target; DependencyProperty targetProperty = bindingExpression.TargetProperty; var value = GetValueOfBindingExpression(bindingExpression, target, targetProperty); return value; } } } using System; using System.Collections.Generic; using System.Linq; using System.Windows; using static System.Windows.Media.VisualTreeHelper; namespace CommonCore.Helpers { public static partial class VisualTreeHelper { public static IEnumerable<DependencyObject> GetChildren(this DependencyObject parent) { ArgumentNullException.ThrowIfNull(parent); Queue<DependencyObject> queue = new Queue<DependencyObject>(16); queue.Enqueue(parent); while (queue.Count != 0) { DependencyObject current = queue.Dequeue(); yield return current; int count = GetChildrenCount(current); for (int i = 0; i < count; i++) { queue.Enqueue(GetChild(current, i)); } } } public static IEnumerable<T> GetChildren<T>(this DependencyObject parent) where T : DependencyObject => parent.GetChildren().OfType<T>(); public static T GetFirstChild<T>(this DependencyObject parent) where T : DependencyObject => (T)parent.GetChildren().FirstOrDefault(child => child is T); } } using System.Globalization; using System.Windows.Controls; using System.Windows.Data; using CommonCore; namespace Core2024.SO.AlexeyTitov.question79081208 { public class OrderIDValidationRule : ValidationRule { public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int id; switch (value) { case int _id: id = _id; break; case string text: id = int.Parse(text, cultureInfo); break; case BindingExpressionBase bindingExpression: var eee = bindingExpression.GetSourceValue(); var t = eee.GetType(); id = (int)(bindingExpression.GetSourceValue() ?? 0); break; default: id = int.MinValue; break; } if (id < 0 || id > 100) return new ValidationResult(false, "Значение вне диапазона [0..100]"); return ValidationResult.ValidResult; } } } using System.Collections.ObjectModel; namespace Core2024.SO.AlexeyTitov.question79081208 { public class Order : BaseInpc { private int? _id; public int? ID { get => _id; set => Set(ref _id, value); } } public class OrdersViewMode : BaseInpc { public ObservableCollection<Order> OrderCollection { get; } = new ObservableCollection<Order> ( Enumerable.Range(0, 20).Select(_ => new Order() { ID = Random.Shared.Next(-20, 120) }) ); } } <Window x:Class="Core2024.SO.AlexeyTitov.question79081208.TestErrorHandlerWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Core2024.SO.AlexeyTitov.question79081208" mc:Ignorable="d" Title="TestErrorHandlerWindow" Height="450" Width="800"> <Window.DataContext> <local:OrdersViewMode/> </Window.DataContext> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ItemsControl x:Name="MyItemsControl" ItemsSource="{Binding Path=OrderCollection}" Validation.Error="OnOrderError"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBox x:Name="MyTextBox"> <TextBox.Text> <Binding Path="ID" Mode="TwoWay" NotifyOnValidationError="True"> <Binding.ValidationRules> <!--<local:OrderIDValidationRule ValidationStep="ConvertedProposedValue"/>--> <local:OrderIDValidationRule ValidationStep="ConvertedProposedValue" ValidatesOnTargetUpdated="True"/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Button x:Name="MyButton" Grid.Row="1" Margin="5" Padding="15 5" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"> </Button> <x:Code> <![CDATA[ private void OnOrderError(object sender, ValidationErrorEventArgs e) { bool hasError = ((DependencyObject)sender).GetChildren().Any(Validation.GetHasError); MyButton.IsEnabled = !hasError; } ]]> </x:Code> </Grid> </Window>

回答 1 投票 0

是否可以动态告诉 NLog 记录到哪个目标?

我想在我的 WPF 应用程序中实现 AppDomain.FirstChanceException,以便有选择地记录发生的每个异常(无论是否已处理)。我不想将这些异常记录到我拥有的目标中

回答 2 投票 0

如何使用 EmguCV 在 C# 中将 Mat 转换为位图?

我正在尝试将 Mat 转换为位图以打开我的网络摄像头,但没有成功。但是,与此问题相比,我看到了一个具有相同上下文的问题,但没有其他用户的任何答案:

回答 3 投票 0

在列表视图的一行中显示具有单独单击操作的三个项目(c# WPF)

我正在与列表视图作斗争。 我有这个列表视图: 我正在与列表视图作斗争。 我有这个列表视图: <ListView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" x:Name="listViewCombined" ItemTemplate="{StaticResource ItemTemplate}" Margin="5"> <ListView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel/> </ItemsPanelTemplate> </ListView.ItemsPanel> </ListView> 这是模板: <Window.Resources> <DataTemplate x:Key="ItemTemplate"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Text="{Binding Dispo}" Grid.Column="0" Margin="5" MouseLeftButtonDown="DispoItem_Click"/> <TextBlock Text="{Binding MATNR}" Grid.Column="1" Margin="5" MouseLeftButtonDown="MATNRItem_Click"/> <TextBlock Text="{Binding MAKTG}" Grid.Column="2" Margin="5" MouseLeftButtonDown="MAKTGItem_Click"/> </Grid> </DataTemplate> </Window.Resources> 上面代码的结果: 但是我试图将其放在一行中(就像一组),并将每个新组放在行中 每列都需要有单独的点击操作。 首先,我开始使用 3 个列表视图,但每个视图都有自己的垂直滚动条,并且一行中的项目属于在一起。所以我需要一个包含三列的滚动视图,每列都有自己的点击操作 首先,您应该看看 WPF 中的 MVVM 模式,并使用 ViewModel、命令和绑定:) 但这完全是另一个主题。 要处理手头的问题,定义点击处理程序很容易。在 XAML 中,只需执行您所做的操作,处理程序后面的代码如下所示: private void DispoItem_Click(object sender, MouseButtonEventArgs e) { } 您可以通过 TextBlock 参数轻松访问 sender。

回答 1 投票 0

在 WPF 中设置电话号码的文本框格式

我在 WPF 窗口中有一个 DataGrid。如何在 DataGrid 中以“(999)999-9999”的格式显示电话号码字符串列? DataGrid 中的电话号码列使用 TextBlock ...

wpf
回答 3 投票 0

如何在wpf c#中对齐单选按钮控件,控件的按钮比文本稍高。如何将它们对齐在同一高度?

<GroupBox Grid.Row="1" Header="Folder Selection" Margin="0,0,0,10"> <StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,10"> <RadioButton Content="Save in Same Folder" IsChecked="{Binding IsSaveInSameFolder}" FontSize="16" VerticalAlignment="Center"/> <RadioButton Content="Save in Custom Folder" IsChecked="{Binding IsSaveInCustomFolder}" FontSize="16" VerticalAlignment="Center" Margin="20,0"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,10"> <TextBox Width="300" Text="{Binding SelectedFolderPath}" FontSize="14" VerticalAlignment="Center" IsEnabled="{Binding IsSaveInCustomFolder}" /> <Button Content="Browse" Width="80" Height="30" VerticalAlignment="Center" Margin="10,0,0,0" Command="{Binding BrowseFolderCommand}" IsEnabled="{Binding IsSaveInCustomFolder}"/> </StackPanel> </StackPanel> </GroupBox> 设计师的结果: 在屏幕截图图像中,我用红色圆圈标记了第二个,以更好地解释我的意思,即按钮或单选按钮的选择与单选按钮文本不对齐。 多亏了副驾驶,我才能够修好它。 这是工作代码: <GroupBox Grid.Row="1" Header="Folder Selection" Margin="0,0,0,10"> <StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,10"> <RadioButton Content="Save in Same Folder" IsChecked="{Binding IsSaveInSameFolder}" FontSize="16" VerticalAlignment="Center" VerticalContentAlignment="Center"/> <RadioButton Content="Save in Custom Folder" IsChecked="{Binding IsSaveInCustomFolder}" FontSize="16" VerticalAlignment="Center" VerticalContentAlignment="Center" Margin="20,0"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="0,0,0,10"> <TextBox Width="300" Text="{Binding SelectedFolderPath}" FontSize="14" VerticalAlignment="Center" IsEnabled="{Binding IsSaveInCustomFolder}" /> <Button Content="Browse" Width="80" Height="30" VerticalAlignment="Center" Margin="10,0,0,0" Command="{Binding BrowseFolderCommand}" IsEnabled="{Binding IsSaveInCustomFolder}"/> </StackPanel> </StackPanel> </GroupBox>

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.