将 ItemTemplate 中的元素绑定到 Windows Phone 7 中 ItemSource 之外的值

发布于 2024-10-02 08:12:39 字数 3977 浏览 2 评论 0原文

我有一个自定义的UserControl,它由一个ListBox 和一个DataTemplate 组成。 ListBox 获取其在 XAML 中设置的源,DataTemplate 中的元素从 Binding 获取其值。

我的 UserControl XAML 如下所示:

<UserControl x:Class="Test.UserControls.TracksListBox"
    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:converters="clr-namespace:Test.Converters"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    mc:Ignorable="d"
    d:DesignHeight="480" d:DesignWidth="480"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Name="this">

<UserControl.Resources>
    <converters:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <CheckBox Grid.Row="0" IsChecked="{Binding Show}"/>
    <ListBox Grid.Row="1" Name="List">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel VerticalAlignment="Top"
                            Margin="0 5 0 5">
                    <TextBlock Text="{Binding Title}"/>
                    <CheckBox IsChecked="{Binding ElementName=this, Path=Show}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

和代码隐藏:

namespace Test.UserControls
{
    public partial class TracksListBox : UserControl
    {
        public static readonly DependencyProperty TracksListProperty =
            DependencyProperty.Register("TracksList",
            typeof(List<Track>),
            typeof(TracksListBox),
            new PropertyMetadata(null, OnTracksListChanged));

        public static readonly DependencyProperty ShowProperty =
            DependencyProperty.Register("Show",
            typeof(bool),
            typeof(TracksListBox),
            new PropertyMetadata(false));

        public TracksListBox()
        {
            InitializeComponent();
        }

        public List<Track> TracksList
        {
            get
            {
                return (List<Track>)GetValue(TracksListProperty);
            }
            set
            {
                SetValue(TracksListProperty, value);
            }
        }

        public bool Show
        {
            get
            {
                return (bool)GetValue(ShowProperty);
            }
            set
            {
                SetValue(ShowProperty, value);
            }
        }

        private static void OnTracksListChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            (obj as TracksListBox).OnTracksListChanged((List<Track>)args.OldValue, (List<Track>)args.NewValue);
        }

        protected virtual void OnTracksListChanged(List<Track> oldValue, List<Track> newValue)
        {
            List.ItemsSource = newValue;
        }
    }
}

在我的 MainPage.xaml 中,我这样使用它:

<userControls:TracksListBox x:Name="TopTracksListBox"
                TracksList="{Binding ElementName=this, Path=TopTracks}"
                Show="True"/>

我的问题是 ListBox 内的 CheckBox DataTemplate 赢了无法从 Show 获取值。不过,Grid.Row="0" 中的另一个 CheckBox 获得了正确的值...如何从我的 UserControl 绑定值在 ListBoxDataTemplate 内?

I have a custom UserControl that consists of a ListBox with a DataTemplate.
The ListBox gets it's source set in XAML and the elements in the DataTemplate gets it's values from Binding.

My UserControl XAML looks like this:

<UserControl x:Class="Test.UserControls.TracksListBox"
    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:converters="clr-namespace:Test.Converters"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    mc:Ignorable="d"
    d:DesignHeight="480" d:DesignWidth="480"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Name="this">

<UserControl.Resources>
    <converters:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <CheckBox Grid.Row="0" IsChecked="{Binding Show}"/>
    <ListBox Grid.Row="1" Name="List">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel VerticalAlignment="Top"
                            Margin="0 5 0 5">
                    <TextBlock Text="{Binding Title}"/>
                    <CheckBox IsChecked="{Binding ElementName=this, Path=Show}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

And the code-behind:

namespace Test.UserControls
{
    public partial class TracksListBox : UserControl
    {
        public static readonly DependencyProperty TracksListProperty =
            DependencyProperty.Register("TracksList",
            typeof(List<Track>),
            typeof(TracksListBox),
            new PropertyMetadata(null, OnTracksListChanged));

        public static readonly DependencyProperty ShowProperty =
            DependencyProperty.Register("Show",
            typeof(bool),
            typeof(TracksListBox),
            new PropertyMetadata(false));

        public TracksListBox()
        {
            InitializeComponent();
        }

        public List<Track> TracksList
        {
            get
            {
                return (List<Track>)GetValue(TracksListProperty);
            }
            set
            {
                SetValue(TracksListProperty, value);
            }
        }

        public bool Show
        {
            get
            {
                return (bool)GetValue(ShowProperty);
            }
            set
            {
                SetValue(ShowProperty, value);
            }
        }

        private static void OnTracksListChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            (obj as TracksListBox).OnTracksListChanged((List<Track>)args.OldValue, (List<Track>)args.NewValue);
        }

        protected virtual void OnTracksListChanged(List<Track> oldValue, List<Track> newValue)
        {
            List.ItemsSource = newValue;
        }
    }
}

In my MainPage.xaml I use it like this:

<userControls:TracksListBox x:Name="TopTracksListBox"
                TracksList="{Binding ElementName=this, Path=TopTracks}"
                Show="True"/>

My problem here is that the CheckBox inside the ListBox DataTemplate won't get the value from Show. The other CheckBox in Grid.Row="0" though, gets the correct value... How do I bind a value from my UserControl inside the DataTemplate of the ListBox?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雨的味道风的声音 2024-10-09 08:12:39

这一定是一个错误,无论我尝试什么,CheckBox 的 DataContext 总是以 null 或 Track 结束。如果你想解决这个问题,你可以添加它,直到这个问题得到解决

<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel VerticalAlignment="Top" 
                Margin="0 5 0 5">
            <TextBlock Text="{Binding Title}"/>
            <CheckBox Loaded="CheckBox_Loaded"/>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

,然后在加载后在代码中设置绑定

private void CheckBox_Loaded(object sender, RoutedEventArgs e)
{
    CheckBox checkBox = sender as CheckBox;
    Binding isCheckedBinding = new Binding("Show");
    isCheckedBinding.Source = this;
    checkBox.SetBinding(CheckBox.IsCheckedProperty, isCheckedBinding);
}

This must be a bug, no mather what I tried the DataContext of the CheckBox always ended up being null or a Track. If you want to work around it you can add this until this gets fixed

<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel VerticalAlignment="Top" 
                Margin="0 5 0 5">
            <TextBlock Text="{Binding Title}"/>
            <CheckBox Loaded="CheckBox_Loaded"/>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

and then set the Binding in code behind once it is Loaded

private void CheckBox_Loaded(object sender, RoutedEventArgs e)
{
    CheckBox checkBox = sender as CheckBox;
    Binding isCheckedBinding = new Binding("Show");
    isCheckedBinding.Source = this;
    checkBox.SetBinding(CheckBox.IsCheckedProperty, isCheckedBinding);
}
得不到的就毁灭 2024-10-09 08:12:39

我将您的代码放入应用程序中的用户控件中,将 Track 更改为 string 并且没有将任何内容绑定到列表,但我仍然看到显示一个复选框和绑定Show 到 IsChecked 对我有用。

I dropped your code into a user control in an app, changed Track to string and didn't bind anything to the list but I still saw a checkbox displayed and the binding of Show to the IsChecked worked for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文