【问题标题】:Creating a custom styled WPF Checkbox purely in the code behind纯粹在后面的代码中创建自定义样式的 WPF 复选框
【发布时间】:2011-01-24 16:25:12
【问题描述】:

我正在尝试创建一个自定义 CheckBox 控件,该控件理想情况下由一个蓝色十字表示,当鼠标鼠标悬停事件发生时,它会变成较浅的蓝色阴影,并在单击时触发一个 Click 事件。

我已经看到在 XAML 代码中使用控制模板和样式来执行此操作的方法,但并非纯粹是在后面的代码中。我之前在代码中创建了自定义样式并很好地应用了它们,但是这次我遇到了自定义数量的问题,例如将整个复选框替换为蓝色十字的图像。

有人知道这样做的标准方法吗?您能否在 XAML 代码中创建一个完整的模板样式,然后在后面的代码中为您的新复选框对象设置属性时引用该模板?

提前致谢。

【问题讨论】:

    标签: c# wpf-controls styles


    【解决方案1】:

    我讨厌这样做,因为它破坏了 XAML 的声明方法,但有时您需要这样做。

    话虽如此,请查看 FrameworkElementFactory 类来构建您的 XAML。这是一个非常整洁的图案。以下 sn-p 显示了我在代码中为 ListView 创建 DataTemplate 的位置。我需要根据一个月中的天数为时间报告应用程序动态添加元素。

           GridView gv = new GridView();
            int i = 0;
            foreach (string s in vm.DateList)
            {
                string column = string.Format("DisplayTime[{0}].Hours", i);
                DataTemplate dt = new DataTemplate();
    
                DateTime date = DateTime.Parse(s);
    
                bool isWeekday = true;
    
                if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
                {
                    isWeekday = false;
                }
    
                Binding binding = new Binding();
                binding.Path = new PropertyPath(column);
                binding.Mode = BindingMode.TwoWay;
    
                FrameworkElementFactory gridElement = new FrameworkElementFactory(typeof(Grid));
                gridElement.SetValue(Grid.WidthProperty, 60.0);
                gridElement.SetValue(Grid.HeightProperty, 94.0);
                gridElement.SetValue(Grid.MarginProperty, new Thickness(0.0, 0.0, 0.0, 4.0));
    
                if (!isWeekday)
                {
                    gridElement.SetValue(Grid.BackgroundProperty, new SolidColorBrush(Color.FromRgb(65, 65, 65)));
                }
    
    
                FrameworkElementFactory txtelement = new FrameworkElementFactory(typeof(TextBox));
                txtelement.SetBinding(TextBox.TextProperty, binding);
                txtelement.SetValue(TextBox.WidthProperty, 40.0);
                txtelement.SetValue(TextBox.HeightProperty, 20.0);
                txtelement.SetValue(TextBox.VerticalAlignmentProperty, VerticalAlignment.Center);
                txtelement.SetValue(TextBox.HorizontalAlignmentProperty, HorizontalAlignment.Center);
                txtelement.SetValue(TextBox.TextAlignmentProperty, TextAlignment.Right);
    
                gridElement.AppendChild(txtelement);
    
                dt.VisualTree = gridElement;
    
                gv.Columns.Add(new GridViewColumn()
                {
                    Header = s,
                    //                            DisplayMemberBinding = new Binding(column),
                    CellTemplate = dt
                });
                i++;
            }
    
            ETCListView.View = gv;
    

    【讨论】:

    • 我同意,它确实不是更可取的方法,但不幸的是,它是我们在当前场景中所坚持的(管理忽视等)。FrameworkElementFactory 看起来非常适合我需要的东西,有点像我希望会存在于框架中。我会给它一个狂欢,看看它是怎么回事,干杯!
    • 这很好用,给了我我需要的控制。但我唯一无法解决的是,哪个属性实际上控制了 CheckBox 的可视化表示。在我读过的 XAML 示例中,它位于“Path”元素中。但是,除了为其设置自定义模板之外,我看不到任何明显的方法可以从 FrameWorkElementFactory 获得它,这让我回到了第一方。有什么想法/有人遇到过这个问题吗?
    • 我最终作弊并使用带有 MouseOver 和 OnClick 事件的图像,因为这最终有足够的行为来做我们需要的事情。但是,我对您的代码所做的实验表明它运行良好,所以谢谢。希望这可以帮助其他人。
    猜你喜欢
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 2020-04-18
    • 2010-11-20
    • 2010-09-26
    • 2021-05-20
    相关资源
    最近更新 更多