【发布时间】:2016-10-28 07:48:18
【问题描述】:
我正在为 UWP 应用创建模板化控件,但在尝试在嵌套的 DataTemplate 中绑定时遇到了障碍。这是我在 Themes/Generic.xaml 中的控制 XAML:
<Style TargetType="local:EnhancedListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:EnhancedListView">
<Grid HorizontalAlignment="Stretch">
<Grid.Resources>
<DataTemplate x:Key="ListViewTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" Grid.Column="0" />
<TextBlock Text="{Binding}" Grid.Column="1" />
</Grid>
</DataTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" Grid.Row="0">Hello</CheckBox>
<ListView Grid.Row="1" ItemsSource="{TemplateBinding ItemsSource}" ItemTemplate="{StaticResource ListViewTemplate}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是我的实际控制/转换器:
public class EnhancedListView : Control
{
public EnhancedListView()
{
DefaultStyleKey = typeof(EnhancedListView);
}
public object ItemsSource
{
get { return GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(object), typeof(EnhancedListView), new PropertyMetadata(null));
public bool IsCheckModeEnabled
{
get { return (bool)GetValue(IsCheckModeEnabledProperty); }
set { SetValue(IsCheckModeEnabledProperty, value); }
}
public static readonly DependencyProperty IsCheckModeEnabledProperty = DependencyProperty.Register("IsCheckModeEnabled", typeof(bool), typeof(EnhancedListView), new PropertyMetadata(null));
}
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotSupportedException();
}
}
这是 MainPage.xaml:
<local:EnhancedListView IsCheckModeEnabled="False" x:Name="ctlListView">
</local:EnhancedListView>
最后,我的 MainPage.xaml.cs:
public MainPage()
{
this.InitializeComponent();
ctlListView.ItemsSource = new List<string> { "Item 1", "Item 2" };
}
正如我所料,当页面加载时,第一个复选框被隐藏,因为 IsCheckModeEnabled 为 false,但嵌套在 DataTemplate 中的所有复选框仍然可见。
我已尝试按照建议 here 将其包装到 StaticResource 中,但它不适用于某些复杂类型,例如在我的 DataTemplate 中嵌套另一个 DataTemplate。
我确定这里的 Visibility 属性的绑定不太正确:
<CheckBox Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" Grid.Column="0" />
感谢您的帮助!
【问题讨论】:
-
如果没有可靠地重现问题的良好minimal reproducible example,就不可能确定问题出在哪里,更不用说最好的解决方法了。但看起来您似乎错误地认为
ListView中项目的模板化父项与包含该ListView的模板的模板化父项相同。如果这还不足以为您指明正确的方向,请改进您的问题。 -
写
DataContext="{Binding}"的意义何在? -
@PeterDuniho - 我添加了额外的细节来改进这个问题。我也不会“错误地认为”
ListView项的模板父项与父容器相同,只是不知道如何表示并绑定到它。 -
@Clemens - 对于我的最终产品来说,将整个对象绑定为 CheckBox 的一部分非常重要。我从我的示例中删除了它。