我正在为一个更大的应用程序开发大型插件组件。这个特定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