首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DataTemplate中的XAML TemplateBinding

DataTemplate中的XAML TemplateBinding
EN

Stack Overflow用户
提问于 2016-06-26 10:03:48
回答 2查看 2.1K关注 0票数 0

我正在为一个UWP应用程序创建一个模板化的控件,当我试图在一个嵌套的DataTemplate中绑定时遇到了一个问题。下面是我在Themes/Generic.xaml中的控件XAML:

代码语言:javascript
复制
<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>

下面是我的实际控制/转换器:

代码语言:javascript
复制
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:

代码语言:javascript
复制
<local:EnhancedListView IsCheckModeEnabled="False" x:Name="ctlListView">
</local:EnhancedListView>

最后,我的MainPage.xaml.cs:

代码语言:javascript
复制
    public MainPage()
    {
        this.InitializeComponent();

        ctlListView.ItemsSource = new List<string> { "Item 1", "Item 2" };
    }

正如我所期望的那样,当页面加载时,第一个复选框是隐藏的,因为IsCheckModeEnabled为false,但是嵌套在DataTemplate中的所有复选框仍然可见。

我曾尝试按照建议的here将其包装到StaticResource中,但它不适用于某些复杂类型,例如在我的DataTemplate中嵌套另一个DataTemplate。

我确信绑定在这里的可见性属性上是不太正确的:

<CheckBox Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" Grid.Column="0" />

谢谢你的帮忙!

EN

回答 2

Stack Overflow用户

发布于 2016-06-26 18:06:51

这只是一个猜测,但是这个怎么样:

代码语言:javascript
复制
<CheckBox Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:EnhancedListView}, Converter={StaticResource BooleanToVisibilityConverter}, Path=IsCheckModeEnabled}" DataContext="{Binding}" Grid.Column="0" />

顺便说一句:伙计,这太复杂了.

票数 0
EN

Stack Overflow用户

发布于 2016-06-26 23:24:50

我相信我找到了一个“干净”的解决方案。我创建了一个新的EnhancedListViewItem类,它可以模拟EnhancedListView.上的属性,然后我独立于父EnhancedListView.对该EnhancedListViewItem进行分配和样式化。下面是我更新后的Generic.xaml:

代码语言:javascript
复制
<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>

下面是我更新后的控件代码:

代码语言:javascript
复制
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));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38034606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档