Я пытаюсь динамически создать и присвоить DataTemplate
HeaderTemplate
из DataGrid
через код. Для этого у меня есть метод GetDatatemplate(string fromstring)
, который определяет литерал XML, а затем использует его для создания DataTemplate
. Это работает отлично, пока я не включаю обработчик события MouseLeftButtonDown
в DataTemplate
.Как назначить обработчик события для DataTemplate в коде?
Мои DataTemplate
сохраняются в string
переменной называется StringHeaderTemplate
в коде-позади MainWindow.xaml.cs
:
private string StringHeaderTemplate [email protected]"<DataTemplate>
<DataTemplate.Resources>
<ControlTemplate x:Key=""imgNo"" TargetType=""{x:Type Control}"">
<Image Source = ""pack://application:,,,/Images/upArrow.png"" />
</ControlTemplate >
<ControlTemplate x:Key=""imgUp"" TargetType=""{x:Type Control}"">
<Image Source = ""pack://application:,,,/Images/upArrow.png"" />
</ControlTemplate >
<ControlTemplate x:Key=""imgDown"" TargetType=""{x:Type Control}"" >
<Image Source = ""pack://application:,,,/Images/downArrow.png"" />
</ControlTemplate >
</DataTemplate.Resources>
<Grid Background=""Transparent"" MouseLeftButtonDown=""Grid_MouseLeftButtonDown"">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content=""Hello""/>
<TextBlock Grid.Row=""1"" HorizontalAlignment= ""Center"" Text = ""TextBlock"" />
<CheckBox Grid.Row= ""2"" HorizontalAlignment= ""Center"" IsChecked= ""True"" />
</Grid >
</DataTemplate>";
и метод, который получает DataTemplate
:
private DataTemplate GetDatatemplate(string fromstring)
{
ParserContext context = new ParserContext();
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
return (DataTemplate)XamlReader.Parse(fromstring, context);
}
Тогда я просто применить этот DataTemplate
к HeaderTemplate
из DataGrid
:
private void dg_AutoGeneratingColumn_1(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataTemplate dtCell = null;
DataTemplate dtHeader = null;
string dtString = string.Empty;
string dtHeaderString = string.Empty;
switch(Type.GetTypeCode(e.PropertyType))
{
case TypeCode.String:
dtString = StringTemplate.Replace("xxColumnxx", e.PropertyName);
dtHeaderString=StringHeaderTemplate;
break;
}
if(!string.IsNullOrEmpty(dtString))
{
dtCell = GetDataTemplateForDataGrid(dtCellString);
dtHeader = GetDataTemplateForDataGrid(dtHeaderString);
DataGridTemplateColumn c = new DataGridTemplateColumn()
{
CellTemplate = dtCell,
HeaderTemplate = dtHeader,
};
e.Column = c;
}
}
обработчик событий очень прост:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show(DateTime.Now.ToString());
}
Исключение я получаю это XamlParseException, который имеет InnerException типа ArgumentException, который говорит:
«Невозможно привязать к целевой метод, потому что его подпись или безопасность прозрачность несовместима с прозрачностью типа делегата. "
Любые идеи, что делать?
Update:
Я пытался связать через Command
, однако CallSortingCommand
не называется. Может быть, вы знаете, что я делаю неправильно?
<Grid Background=""Transparent"">
<i:Interaction.Triggers>
<i:EventTrigger EventName=""MouseLeftButtonDown"">
<prism:InvokeCommandAction Command = ""{Binding
RelativeSource={RelativeSource AncestorType=Window,
Mode=FindAncestor}, Path=DataContext.CallSortingCommand}"" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content=""Hello""/>
<TextBlock Grid.Row=""1"" HorizontalAlignment= ""Center"" Text = ""TextBlock"" />
CheckBox Grid.Row= ""2"" HorizontalAlignment= ""Center"" IsChecked= ""True"" />
</Grid >
Что StringTemplate? –
'private string StringHeaderTemplate = @" 'omg stop прямо там ... что вы делаете? DataTemplates должны быть определены в ваших ресурсах. Если вам нужна настраиваемая логика для выбора шаблона данных, создайте и используйте DataTemplateSelector Что происходит, у меня даже нет –
Will