#silverlight #xaml #data-binding #silverlight-4.0 #datatemplate
#Silverlight #xaml #Привязка к данным #Silverlight-4.0 #DataTemplate
Вопрос:
У меня есть пользовательский элемент управления, который имеет свойство зависимости ICommand. Я хотел бы привязаться к этому свойству изнутри DataTemplate. Чтобы было понятнее, вот мой код:
Класс DataForm:
public class DataForm : Form
{
#region Properties
public ICommand HideForm
{
get { return (ICommand)GetValue(HideFormProperty); }
set { SetValue(HideFormProperty, value); }
}
public static readonly DependencyProperty HideFormProperty =
DependencyProperty.Register("HideForm", typeof(ICommand), typeof(DataForm), new PropertyMetadata(null));
#endregion
#region Ctors
public DataForm(Guid formId, String title)
: base(formId, title)
{
this.Template = Application.Current.Resources["DataFormDefaultTemplate"] as ControlTemplate;
}
public DataForm()
: this(Guid.NewGuid(), "bla")
{
}
#endregion
#region Methods
public override void OnApplyTemplate()
{
if (HeaderTemplate == null)
{
HeaderTemplate = Application.Current.Resources["DefaultFormHeaderTemplate"] as DataTemplate;
}
base.OnApplyTemplate();
}
#endregion
}
ControlTemplate формы данных:
<ControlTemplate x:Name="DataFormDefaultTemplate" TargetType="my:DataForm">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" ContentTemplate="{TemplateBinding HeaderTemplate}"></ContentPresenter>
<ContentPresenter Grid.Row="1" ContentTemplate="{TemplateBinding BodyTemplate}"></ContentPresenter>
<ContentPresenter Grid.Row="2" ContentTemplate="{TemplateBinding FooterTemplate}"></ContentPresenter>
</Grid>
</ControlTemplate>
DataTemplate, с которого я хочу привязаться к команде HideForm:
<DataTemplate x:Name="DefaultFormHeaderTemplate">
<Grid HorizontalAlignment="Stretch">
<my:TextField FieldViewStyle="{StaticResource formLabelStyle}" Value="Form Title" Mode="View"></my:TextField>
<my:ImageButtonField ImagePath="../Images/Popup_Close.png"
CommandToExecute="{Binding HideForm}"
HorizontalAlignment="Right" Width="8" Height="8"></my:ImageButtonField>
</Grid>
</DataTemplate>
Примечание: CommandToExecute
правильно работает с ImageButtonField. Я уже протестировал это.
Код для создания экземпляра формы данных:
DataForm form = new DataForm();
form.BodyTemplate = Application.Current.Resources["DataFormBodyTemplate"] as DataTemplate;
form.FooterTemplate = Application.Current.Resources["DataFormFooterTemplate"] as DataTemplate;
form.HideForm = new DelegateCommand(CloseIt);
Как мне заставить это работать? В принципе, идеальным сценарием является возможность привязки к этой команде (и другим свойствам) в шаблоне данных из ViewModel без необходимости добавлять это свойство ( HideForm
в данном случае) к DataForm
классу. Разве DataContext не должен наследоваться и — теоретически — то, что я говорю, должно работать?
Комментарии:
1. Ни у кого, кроме вас, нет ваших
Form
,TextField
ниImageButtonField
классов, поэтому никто, кроме вас, не может запустить этот код, чтобы выяснить, в чем проблема. В частности, как aForm
использует aHeaderTemplate
? Попробуйте вместо этого предоставить SSCCE .2. @Luke Woodward: Это будет сложно, потому что в цепочке наследования есть несколько классов, но я уверен, что проблема связана с DataTemplate. Я хочу знать, возможно ли то, чего я пытаюсь достичь, или это ограничение Silverlight 4…
Ответ №1:
Я использую EventToCommand в MVVM Light, см. Пример кода ниже.
<UserControl.Resources>
<ContentControl x:Key="ViewModel" Content="{Binding}" />
</UserControl.Resources>
.. Your code here ..
<my:ImageButtonField ImagePath="../Images/Popup_Close.png"
CommandToExecute="{Binding HideForm}"
HorizontalAlignment="Right" Width="8" Height="8">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<Command:EventToCommand Command="{Binding Content.YourCommand, Source={StaticResource ViewModel}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</my:ImageButtonField>
Вы можете прочитать больше о EventToCommand <- здесь .
Ответ №2:
Оказалось, что нет способа сделать это с помощью a DataTemplate
, если вы не используете прокси-сервер привязки. Другой способ — использовать ControlTemplate
вместо a и привязывать к Template
свойству a ContentControl
вместо использования a ContentPresenter