WPF:如何在XAML中使用您自己的C#代码中的变量来创建样式

WPF和XAML新手在这….

我需要将XAML代码中的WPF TriggerDataTrigger到除XAML控件类之外的类中的某些C#代码中。 这非常令人沮丧,因为我读过的所有28,000个教程只给出了涉及已经存在的属性的 TriggerDataTrigger一个简单示例(例如MouseOver ),它们都没有给出如何将它与您自己的C#代码绑定的示例。

我有一个显示各种报告类型的屏幕。 所有报告类型的XAML都是相同的,但对于诊断报告,我的要求是DataGrid单元格配置为TextBlock.TextAlignment="Left" ,而所有其他报告(即默认值)应为TextBlock.TextAlignment="Center" 。 (还有一些其他差异;为了简洁起见,我只是说这是唯一的区别。)我真的不想将整个XAML复制到特殊情况下的诊断报告中,因为其中99%将是与其他报告相同。

要使用Trigger,我想也许我需要我的类inheritanceDependencyObject所以我可以在其中定义DependencyProperty(作为一个WPF新手,我意识到我可能会说一些非常古怪的东西)。 所以在我的C#代码中,我有一个类…

 namespace MyApplication { public enum SelectedReportType { EquipSummary, EventSummary, UserSummary, DiagSummary } public sealed class ReportSettingsData : DependencyObject { private static ReportSettingsData _instance; // singleton static ReportSettingsData() { new ReportSettingsData(); } private ReportSettingsData() // private because it's a singleton { if (_instance == null) // only true when called via the static constructor _instance = this; // set here instead of the static constructor so it's available immediately SelectedReport = SelectedReportType.EquipSummary; // set the initial/default report type } public static ReportSettingsData Instance { get { return _instance; } } public static SelectedReportType SelectedReport { get { return (SelectedReportType)Instance.GetValue(SelectedReportProperty); } set { Instance.SetValue(SelectedReportProperty, value); } } public static readonly DependencyProperty SelectedReportProperty = DependencyProperty.Register("SelectedReport", typeof(SelectedReportType), typeof(ReportSettingsData)); } } 

所以在我的XAML文件中,我玩过各种各样的TriggerDataTrigger ,并且无法弄清楚如何使它工作。 在每种情况下,诊断报告都具有与其他报告相同的默认特征。

        <!--   -->         

如何在ReportSettingsData.SelectedReport == SelectedReportType.DiagSummaryTrigger我的Trigger

如何在XAML中使用您自己的C#代码中的变量来创建样式

我建议您查看CellTemplate选择器( GridViewColumn.CellTemplateSelector属性(System.Windows.Controls) ),您可以在其中执行代码后面的选择逻辑。

粗略的例子

只需定义资源中所需的模板(4个,但显示为两个)

         

网格单元的Xaml模板用法选择器

      

代码背后

 public class MeetingTemplateSelector : DataTemplateSelector { public DataTemplate EquipTemplate { get; set; } public DataTemplate EventTemplate { get; set; } public DataTemplate UserTemplate { get; set; } protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) { DataTemplate result; switch( ((ReportSettingsData) item).SelectedReport) { case EquipSummary : result = EquipTemplate; break; case EventSummary : result = EventTemplate; break; case UserSummary .. } return result; } } 

更新

根据评论,各种选择使模板建议增长到超过30个模板。 另一种方法可能是使用操作属性扩展目标类来代替触发的操作。 例如,假设我们需要显示红色,在实例上提供它并绑定。

 public Partial MyClassInstance { public Brush ColorMeAs { get { return this.IsValid ? BrushGreen : BrushRed; } } ... other properties as such: } 

然后如此绑定

 Foreground="{Binding ColorMeAs}" 

触发器

以下是从我的存档中提取的数据触发器的示例:

  

您的C#代码看起来很好,并且您已经拥有引用MyApplication命名空间的XML NameSpace声明,因此:

你应该只能使用x:Static标记来访问枚举值,使用枚举标识符,如本例所示(我喜欢这个例子,因为它还展示了如何使用非自定义x:Static以及如何进行一些树遍历以及):

            

在您的情况下,您的枚举标记应为:

Value="{x:Static my:SelectedReportType.DiagSummary}"