Windows Presentation Foundation或WPF是用于在基于Windows的应用程序中呈现用户界面的子系统。
捕获 WPF 运行时 BindingExpression 错误
我们都可以在 Visual Studio 输出窗口中看到运行时 BindingExpression 错误。但是我们可以在运行的应用程序本身中捕获这些事件吗?我听说 WPF 跟踪...这有什么作用吗...
为什么我无法像在 XAML 上那样在代码后面绑定 StringFormat?
这是我的工作示例,它正确绑定了 ViewModel 并正确触发了 StringFormat 和 ValidateMaskDecimal: 这是我的工作示例,它正确绑定了 ViewModel 并正确触发 StringFormat 和 ValidateMaskDecimal: <ListBox x:Name="Difetti" ItemsSource="{Binding Difetti}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBox x:Name="Metro" controls:TextBoxHelper.Watermark="Metro" PreviewTextInput="ValidateMaskDecimal"> <TextBox.Text> <Binding Path="Metro" StringFormat="{}{0:0.0##########}"> </Binding> </TextBox.Text> </TextBox> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> 现在,如果我尝试在后面的代码中执行类似的操作(删除 ListBox,并将唯一的 TextBox 绑定到某个特定 index = 0 处的数据模型): <TextBox x:Name="Metro" controls:TextBoxHelper.Watermark="Metro" PreviewTextInput="ValidateMaskDecimal" /> var data = DataContext as ViewModelData; if (data != null && data.Difetti.Count > 0) { int difettoIndex = 0; Metro.SetBinding(TextBox.TextProperty, new Binding { Source = data, Path = new PropertyPath($"Difetti[{difettoIndex}].Metro"), StringFormat = "{}{0:0.0##########}" }); } 它会抛出 ValueStringBuilder 的 ThrowFormatError 异常: System.FormatException: '输入字符串的格式不正确。'. 我不明白为什么。 我哪里错了?代码不应该给我同样的结果吗? DataModel 上的 Metro 以这种方式配置(可空 decimal): private decimal? metro; public decimal? Metro { get { return metro; } set { SetField(ref metro, value, "Metro"); } } 字符串格式前缀的 {} 特定于 XAML。您在代码中不需要它。 当然,您可以检查在XAML中创建的字符串格式文本。 BindingExpression expression = BindingOperations.GetBindingExpression(Metro, TextBox.TextProperty); string format = expression.ParentBinding.StringFormat; Debug.WriteLine(format);
将我的数据库中的数据绑定到 DataGrid WPF C# MVC 模式
我正在使用 EF Core 和 MVC 模式来创建桌面应用程序(我知道 MVVM 更好,但我被迫在工作中使用 MVC)。如何将数据直接从数据库链接到 Projets.x 中的数据网格...
我在绘制列左对齐或居中对齐的列表视图时遇到问题。我查看了在这里或其他论坛上找到的一些解决方案,但它们似乎适用于所有公司...
我的 WPF 4.5 应用程序有一个小(但烦人)的视觉错误,其中 DataGrid 的单元格在加载时被切断: 屏幕截图的 Dropbox 链接 但是一旦你调整窗口大小(点击正方形但是......
WPF - 从 UserControl 访问 ViewModel 中的 EventHandler
我正在尝试从 MainViewModel 获取 DataGrid 的 SelectionChangedEventHandler 实现,但我不断收到错误,但如果我将 EventHandler 放在 MainWindow 内,它就可以正常工作。 错误 '
我可以通过不同的“API”DLL 仅公开一个 .NET DLL 公共类的一部分吗?
我正在设计一个 WPF 应用程序,它使用大约有 40 个公共类的 DLL。我需要将这些公开,原因有多种,包括易于数据绑定和混淆。我想要一个...
如何在 WPF 桌面应用程序中开发公共 API 对象模型,以允许从另一个 .NET 桌面应用程序进行进程外自动化
我们正在使用 Windows Presentation Foundation 开发一个大型桌面应用程序。目前,该应用程序仅供内部使用,但最终将作为商业产品出售。我现在...
我正在寻找一个允许创建 PDF 运行时的 API。它还应该允许将动态数据和表格包含到 PDF 文档中。我发现了一个名为 aspose.pdf API 的 API,它可以满足我的
将 Microsoft 的拼写检查 Bing API 与 WPF 结合使用,返回零拼写错误
我正在尝试将 Microsoft 的 Bing Spellcheck API 与 WPF 应用程序一起使用。我有一个文本框,可以在其中输入一些文本,然后有一个按钮可以检查文本框中的拼写,并且应该重新...
我刚刚决定开始学习 API 以及如何将其附加到标签。 问题是我一直在查看 GitHub 和 Codeproject,但我找不到任何示例或开源项目......
我需要将 Aero 背景模糊仅应用于自定义形状的 WPF 窗口的一部分。问题是要使用 DWM 应用模糊,我需要为 DwmEnableBlurBehindWindow 提供一个窗口句柄
我在我的解决方案中添加了一些图像,现在它位于 images lowers 文件夹下 解决方案资源管理器内的 ose.png。我想要一种方法将此图像动态加载到我的图像控件中。 我的
所以我一直在四处寻找,但找不到确切的方法。我正在使用 MVVM 创建用户控件,并希望在“Loaded”事件上运行命令。我意识到这需要我...
C# WPF:按下时更改按钮 Context="{Binding Text}"
WPF 编程新手我来自 WinForms。我有两个正在运行的 WinForms 项目/解决方案,我想将它们转换为 WPF。我设法通过 XMAL 和 MainWindowViewModel 但...
我已经阅读了很多有关线程和异步的示例...,但是我无法使 wpf c# 中的 UI 在计算磁盘上的文件时不冻结 - 我无法移动窗口...,我有等待计数
我正在编写一个插件,该插件已加载到源不受我管理的应用程序中。通过 API,我可以获得应用程序的 AvalonDock DockingManager。我想添加一个绑定...
如何正确管理BitmapImage的数据绑定和序列化/反序列化?
这是我的基本代码: 公共类 MyObject { 公共十进制 MyDeciaml { 获取;放; } 公共字符串?我的ImageBase64 { 得到 { 如果(MyImageBase64!=空) ...
在按钮命令上,将 UserControl 上的 ItemControl 项传递到 ViewModel
我想是时候寻求帮助了!我有一个列出 UserControls 的 ItemsControl(称为CompoundCardControl): 我想是时候寻求帮助了!我有一个列出 UserControls 的 ItemsControl(称为CompoundCardControl): <ScrollViewer Grid.Row = "1" VerticalScrollBarVisibility="Auto"> <ItemsControl ItemsSource="{Binding Method.Compounds}"> <ItemsControl.ItemTemplate> <DataTemplate> <control:CompoundCardControl/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ScrollViewer> UserControl 包含一个按钮,用于从 ListView(和 ViewModel)中删除项目: <Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="25"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Margin="5,0,0,0" Text="{Binding Name}" /> <TextBlock Grid.Column="1" Margin="5,0,0,0" Foreground="Gray" FontSize="10" VerticalAlignment="Center" Text="RT"/> <TextBlock Grid.Column="2" Margin="5,0,0,0" Text="{Binding RetentionTime , StringFormat= '\{0\} minutes'}" /> <Button Grid.Column="3" HorizontalAlignment="Right" Style="{StaticResource menuBarButton}" Command="{Binding DataContext.DeleteCompoundCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding Compound}"> <Image Width="12" Height="12" Source="/Resources/Icons/Delete.png"/> </Button> </Grid> 这是我的父窗口的 ViewModel(但它显然不起作用)”: public class MethodDialogViewModel : ViewModelBase { //properties public DialogModeEnum DialogMode { get; private set; } public string WindowTitle { get { return DialogMode == DialogModeEnum.Add ? "New method" : "Edit method"; } } public string ButtonText { get { return DialogMode == DialogModeEnum.Add ? "Add" : "Update"; } } public Method Method { get; set; } public MethodCompound Compound { get; set; } = new MethodCompound(); //constructor public MethodDialogViewModel(Method method, DialogModeEnum dialogMode) { DialogMode = dialogMode; Method = method; } //commands public RelayCommand DeleteCompoundCommand => new(execute => DeleteCompound(Compound)); private void DeleteCompound(MethodCompound methodCompound) { //Logic not implimented. I just want to see if I can get the object "methodCompound" if (methodCompound != null) { MessageBox.Show(methodCompound.ID); } else { MessageBox.Show("Please select a compound.", "Delete compound", MessageBoxButton.OK, MessageBoxImage.Information); } } } 基本上我想将 ItemsControl 中的 Item(实际上是底层对象)传递给 ViewModel。我怎么做?还是我完全搞砸了? 您的代码存在一些奇怪之处,这似乎导致了为什么没有任何内容按预期工作。 RelayCommand 委托似乎是错误的。根据参数名称execute,您似乎得到了错误的委托签名。 RelayCommand实现的原始签名是ICommand.Execute(object commandParameter): void。这意味着 lambda 的 execute 参数应命名为,例如commandParameter。然后您实际上必须将该参数传递给执行委托。否则,Button.CommandParameter值将丢失,即不转发: 公共 RelayCommand 删除复合命令 => new(commandParameter => DeleteCompound((MethodCompound )commandParameter)); MethodDialogViewModel.Compound属性始终返回相同的实例 Grid.Width内CompoundCardControl上的绑定是多余的,因为Grid会自然拉伸以填充可用空间。 因为您想要滚动 ItemsControl 内部的项目,而不是 ItemsControl 本身,所以必须将 ScrollViewer 添加到 ControlTemplate 的 ItemsControl 中,它包裹着 ItemsPresenter。 <ControlTemplate TargetType="ItemsControl"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ScrollViewer> <ItemsPresenter /> </ScrollViewer> </Border> </ControlTemplate> 请注意,ItemsControl不提供任何性能功能(例如 UI 虚拟化),这可以显着改善较大列表或包含昂贵项目或项目容器的列表的体验。 另一方面,ListBox 是一种高级的 ItemsControl,带有滚动和 具有 UI 虚拟化和一些有用的属性,例如返回当前所选项目的 ListBox.SelectedItem 属性。在您的情况下,您可以将其绑定到 MethodDialogViewModel.Compound 属性。要消除突出显示,您只需覆盖 ListBoxItem.Template: <!-- A ListBoxItem without highlighting. You can add this template to a resource to reuse it. --> <ControlTemplate x:Key="NoHighlightListBoxItemTemplate" TargetType="ListBoxItem"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ContentPresenter /> </Border> </ControlTemplate> 一些一般性说明:自定义控件(例如 UserControl)永远不应该使用自己的 DataContext。例如,当 DataContext 发生变化时,控件就会损坏。由于 Binding.RelativeSource 的目标元素是自定义控件之外的,因此将自定义控件移动到可视化树中的其他位置也会破坏自定义控件。为了防止这种情况,请添加请求将所需数据传递到自定义控件的依赖属性,例如通过数据绑定。然后将内部控件绑定到这些依赖属性。目前尚不清楚为什么在这种情况下使用 UserControl。您可以通过直接在 UserControl 中定义项目的布局来安全地避免 DataTemplate 的开销。如果需要分隔,您可以将 DataTemplate 移动到其自己的文件中。 这与解决您的问题无关,但如果您关心良好的控制设计,则与此相关。这些是一些基础知识。 CompoundCardControl.xaml.cs public partial class CompoundCardControl : UserControl { public MethodCompound Compound { get => (MethodCompound)GetValue(CompoundProperty); set => SetValue(CompoundProperty, value); } public static readonly DependencyProperty CompoundProperty = DependencyProperty.Register( "Compound", typeof(MethodCompound), typeof(CompoundCardControl), new PropertyMetadata(default)); public ICommand DeleteCommand { get => (ICommand)GetValue(DeleteCommandProperty); set => SetValue(DeleteCommandProperty, value); } public static readonly DependencyProperty DeleteCommandProperty = DependencyProperty.Register( "DeleteCommand", typeof(ICommand), typeof(CompoundCardControl), new PropertyMetadata(default)); public CompoundCardControl() { InitializeComponent(); } } CompoundCardControl.xaml <UserControl x:Name="Root"> <Button Style="{StaticResource menuBarButton}" Command="{Binding ElementName=Root, Path=DeleteCommand}" CommandParameter="{Binding ElementName=Root, Path=Compound}"> <Image Source="/Resources/Icons/Delete.png"/> </Button> </UserControl> MainWindow.xaml <Window> <Window.DataContext> <MethodDialogViewModel /> </Window.DataContext> <Window.Resources> <!-- A ListBoxItem without highlighting --> <ControlTemplate x:Key="NoHighlightListBoxItemTemplate" TargetType="ListBoxItem"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ContentPresenter /> </Border> </ControlTemplate> </Window.Resources> <ListBox ItemsSource={Binding Method.Compounds}"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Template" Value="{StaticResource NoHighlightListBoxItemTemplate}" /> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemTemplate> <DataTemplate DataType="{x:Type MethodCompound}"> <control:CompoundCardControl Command="{Biding DeleteCompoundCommand}" Compound="{Binding}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window> MethodDialogViewModel.cs public class MethodDialogViewModel : ViewModelBase { //properties public DialogModeEnum DialogMode { get; private set; } public string WindowTitle { get { return DialogMode == DialogModeEnum.Add ? "New method" : "Edit method"; } } public string ButtonText { get { return DialogMode == DialogModeEnum.Add ? "Add" : "Update"; } } public Method Method { get; set; } // This does never change. Consider to bind it to the ListBox.SelectedItem property public MethodCompound Compound { get; set; } = new MethodCompound(); //constructor public MethodDialogViewModel(Method method, DialogModeEnum dialogMode) { DialogMode = dialogMode; Method = method; } //commands public RelayCommand DeleteCompoundCommand => new(ExecuteDeleteCompoundCommand); private void ExecuteDeleteCompoundCommand(object commandParameter) => DeleteCompound((MethodCompound)commandParameter); private void DeleteCompound(MethodCompound methodCompound) { // methodCompund will never be NULL in the current scenario this.Method.Compunds.Remove(methodCompound); } }
我正在使用反射来获取属性列表,并且我想使用该属性来获取给定属性所绑定到的 WPF 控件的实例。 所以在后面的代码中我想...