绑定到Windows Phone上的DataTemplate的一个元素
本文关键字:一个 元素 Windows Phone 上的 DataTemplate 绑定 | 更新日期: 2023-09-27 18:04:50
简单明了:我需要将ContextMenu
项的一些属性绑定到DataTemplate
中它们的父项的属性。
我找不到访问它的方法,因为ElementName
不起作用,RelativeSource
允许我只使用Self
或TemplatedParent
。
下面是我的代码:
<telerikPrimitives:RadDataBoundListBox Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
ItemsSource="{Binding Transfers.Keys, Source={StaticResource TransfersManager}, Mode=OneWay}">
<telerikPrimitives:RadDataBoundListBox.ItemTemplate>
<DataTemplate>
<toolkit:TransferControl x:Name="TransferControl"
Header="{Binding Converter={StaticResource TransferMonitorToDocumentTitleConverter}}"
IsContextMenuEnabled="False"
Icon="{Binding Converter={StaticResource TransferMonitorToDocumentIconUriConverter}}"
AutoHide="False"
Monitor="{Binding}"
Language="it-IT"
StatusTextBrush="Black"
Foreground="Black">
<toolkit:TransferControl.HeaderTemplate>
<DataTemplate>
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="item1"
IsEnabled="{Binding Monitor Property in the TransferControl object}"
/>
<toolkit:MenuItem Header="item2"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Rectangle Fill="Transparent" Height="30"/>
<ContentControl Content="{Binding}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="Black" />
</StackPanel>
</DataTemplate>
</toolkit:TransferControl.HeaderTemplate>
</toolkit:TransferControl>
</DataTemplate>
</telerikPrimitives:RadDataBoundListBox.ItemTemplate>
我要绑定的是:
<toolkit:MenuItem Header="item1"
IsEnabled="{Binding Monitor Property in the TransferControl object}"
/>
,我想把它绑定到<toolkit:TransferControl x:Name="TransferControl" ... />
对象的Monitor
属性
我可以通过简单地创建一个新的UserControl来保存ListBox的内容来解决这个问题。我使用了LongListSelector。这是一个有效的解决方案。
首先是页面的XAML:<phone:LongListSelector Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<local:WindowsPhoneControl/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
然后是UserControl。这没什么特别的,只是一个包装。
<UserControl x:Class="PivotApp1.WindowsPhoneControl"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<phone:LongListSelector x:Name="TransferControl" Margin="0,0,-12,0"
ItemsSource="{Binding Items}"
toolkit:TiltEffect.IsTiltEnabled="True">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="item1"
IsEnabled="{Binding DataContext.Monitor, ElementName=TransferControl}"/>
<toolkit:MenuItem Header="item2"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
</UserControl>
使用此解决方案,在呈现列表时命中Monitor属性。打开菜单时不会被击中。当然,如果您为monitor触发propertyChanged,它将再次获得该值。
您想要绑定的属性似乎已绑定到DataContext本身。为什么不直接在HeaderTemplate中绑定它(DataContext)呢?您所需要做的就是将Header属性绑定到DataContext,而不是将其转换为其他内容,然后在HeaderTemplate中使用Converter。像这样:
<telerikPrimitives:RadDataBoundListBox.ItemTemplate>
<DataTemplate>
<toolkit:TransferControl x:Name="TransferControl"
Header="{Binding}"
IsContextMenuEnabled="False"
Icon="{Binding Converter={StaticResource TransferMonitorToDocumentIconUriConverter}}"
AutoHide="False"
Monitor="{Binding}"
Language="it-IT"
StatusTextBrush="Black"
Foreground="Black">
<toolkit:TransferControl.HeaderTemplate>
<DataTemplate>
<StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="item1"
IsEnabled="{Binding}"
/>
<toolkit:MenuItem Header="item2"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Rectangle Fill="Transparent" Height="30"/>
<ContentControl Content="{Binding Converter={StaticResource TransferMonitorToDocumentTitleConverter}}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="Black" />
</StackPanel>
</DataTemplate>
</toolkit:TransferControl.HeaderTemplate>
</toolkit:TransferControl>
</DataTemplate>
</telerikPrimitives:RadDataBoundListBox.ItemTemplate>
顺便说一句,我认为你可能装订得太多了。绑定和转换器可能会导致糟糕的性能,有时不绑定会更快更容易。
顺便说一句,我可以问transfermonitortodocumenttitlecconverter做什么?
好像工具箱里有个bug。Header属性的getter将对象强制转换为字符串,因此,即使该属性是object类型,也只能将其设置为字符串——否则会在内部使用的getter中抛出异常。
这是一个可能的解决方案:
像这样扩展TransferControl:
public class TransferControlFixed : TransferControl { public static readonly DependencyProperty HeaderFixedProperty = DependencyProperty.Register("HeaderFixed", typeof(object), typeof(TransferControlFixed), new PropertyMetadata(null)); public object HeaderFixed { get { return GetValue(HeaderFixedProperty); } set { SetValue(HeaderFixedProperty, value); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); var control = (ContentControl)this.GetTemplateChild("Header"); control.SetBinding(ContentControl.ContentProperty, new Binding() { Path = new PropertyPath("HeaderFixed"), Source = this }); } }
使用TransferControlFixed代替TransferControl,绑定HeaderFixed代替Header属性