如何在WPF中从FrameworkElementFactory获取控件类型(UIElement)?

时间:2016-09-15 04:13:40

标签: c# wpf uielement frameworkelementfactory

我正在为一个更大的应用程序开发大型插件组件。这个特定View组件的90%是极其动态的(数据库驱动的)并以编程方式完成。有一个特殊的原因(最小的XAML),所以在盒子外思考。不,我无法回头重新组建一个由1000行代码组成的代码库......这是未来的版本。

我可以通过FrameworkElementFactory设置值,绑定和添加处理程序,但需要访问控件本身来执行其他任务。一个任务是向每个FrameworkElement添加ToolTipService。如果我为每个派生控件添加一个Loaded事件,然后通过将它添加到索引对象集合中来管理它,我能够做到这一点,但这是一种非常难看的方式。

我把这个小片段(下面)放在一起进行测试,但它包含了手头的问题。

MainWindow.xaml

<Window x:Class="FrameworkElementFactory_Control_Testing.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:local="clr-namespace:FrameworkElementFactory_Control_Testing"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="500"
        Height="300"
        mc:Ignorable="d">
    <Grid>
        <StackPanel x:Name="LayoutRoot"
                    Margin="5"
                    Orientation="Vertical" />
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;

namespace FrameworkElementFactory_Control_Testing
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;

            GridObjectCollection = new ObservableCollection<GridObject>() { new GridObject() };
            //GridObjectCollection.Add(new GridObject());

            DoTheGrid();
        }

        public ObservableCollection<GridObject> GridObjectCollection { get; set; }
        public GridObject CurrentGridObject { get; set; }

        private void DoTheGrid()
        {
            DataGrid dg = new DataGrid();

            dg.Margin = new Thickness(5);
            dg.AutoGenerateColumns = false;
            dg.CanUserAddRows = false;
            dg.CanUserDeleteRows = false;
            dg.CanUserSortColumns = false;
            dg.IsReadOnly = true;
            dg.ColumnWidth = new DataGridLength(1, DataGridLengthUnitType.Auto);
            dg.SelectionMode = DataGridSelectionMode.Single;
            dg.SelectedItem = CurrentGridObject;
            dg.ItemsSource = GridObjectCollection;

            DataGridTemplateColumn dgTemplateColumn = new DataGridTemplateColumn();
            FrameworkElementFactory factoryControl = null;

            TextBlock headerName = new TextBlock() { Text = "Button Type" };

            dgTemplateColumn.Header = headerName;

            factoryControl = new FrameworkElementFactory(typeof(Button));
            factoryControl.SetValue(Button.MarginProperty, new Thickness(1));
            factoryControl.SetValue(Button.WidthProperty, Convert.ToDouble("70"));
            factoryControl.SetValue(Button.HeightProperty, Convert.ToDouble("24"));
            factoryControl.SetValue(Button.NameProperty, "btnCLICK_ME");
            factoryControl.SetValue(Button.ContentProperty, "Click Me");
            factoryControl.AddHandler(Button.LoadedEvent, new RoutedEventHandler(ButtonLoaded_Click));

            DataTemplate cellTemplateControl = new DataTemplate();
            cellTemplateControl.VisualTree = factoryControl;
            dgTemplateColumn.CellTemplate = cellTemplateControl;
            dgTemplateColumn.CanUserSort = false;
            dg.Columns.Add(dgTemplateColumn);

            this.LayoutRoot.Children.Add(dg);
        }

        private void ButtonLoaded_Click(object sender, RoutedEventArgs e)
        {
            Button btn = sender as Button;

            //add btn to indexed collection for future reference (this is lame)
        }
    }
}

GridObject.cs

namespace FrameworkElementFactory_Control_Testing
{
    public class GridObject
    {
        public GridObject()
        { }

    }
}

非常感谢任何建设性的帮助。谢谢你们的时间。

CT

0 个答案:

没有答案