我正在为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" />
感谢您的帮助!
答案 0 :(得分:0)
只是一个猜测但是如何:
<CheckBox Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:EnhancedListView}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" DataContext="{Binding}" Grid.Column="0" />
顺便说一句:男人这是错综复杂的......
答案 1 :(得分:0)
我相信我找到了一个更清洁的&#34;有效的解决方案。我创建了一个新的EnhancedListViewItem
类,它可以模仿EnhancedListView.
上的属性然后我分配并EnhancedListViewItem
独立于父EnhancedListView.
的样式这里是我更新的通用的.xaml:
<Style TargetType="local:EnhancedListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:EnhancedListView">
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" Grid.Column="0" />
<ListView Grid.Row="1" ItemsSource="{TemplateBinding ItemsSource}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="local:EnhancedListViewDataItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:EnhancedListViewDataItem">
<Grid HorizontalAlignment="Stretch">
<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>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这里是我更新后的控制代码:
public class EnhancedListView : Control, INotifyPropertyChanged
{
public EnhancedListView()
{
DefaultStyleKey = typeof(EnhancedListView);
}
public event PropertyChangedEventHandler PropertyChanged;
public object ItemsSource
{
get { return GetValue(ItemsSourceProperty); }
set
{
var boundItems = new List<EnhancedListViewDataItem>();
foreach (var obj in (List<string>)value)
{
boundItems.Add(new EnhancedListViewDataItem(this)
{
DataContext = obj
});
}
SetValue(ItemsSourceProperty, boundItems);
}
}
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);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsCheckModeEnabled"));
}
}
public static readonly DependencyProperty IsCheckModeEnabledProperty = DependencyProperty.Register("IsCheckModeEnabled", typeof(bool), typeof(EnhancedListView), new PropertyMetadata(null));
}
public class EnhancedListViewDataItem : ListViewItem
{
public EnhancedListViewDataItem(EnhancedListView listView)
{
_listView = listView;
_listView.PropertyChanged += _listView_PropertyChanged;
DefaultStyleKey = typeof(EnhancedListViewDataItem);
}
private readonly EnhancedListView _listView;
private void _listView_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
IsCheckModeEnabled = _listView.IsCheckModeEnabled;
}
public bool IsCheckModeEnabled
{
get { return (bool)GetValue(IsCheckModeEnabledProperty); }
set { SetValue(IsCheckModeEnabledProperty, value); }
}
public static readonly DependencyProperty IsCheckModeEnabledProperty = DependencyProperty.Register("IsCheckModeEnabled", typeof(bool), typeof(EnhancedListViewDataItem), new PropertyMetadata(null));
}