【问题标题】:How can I get control in DataTemplate?如何在 DataTemplate 中获得控制权?
【发布时间】:2013-02-19 13:28:54
【问题描述】:

所以,我有一个代码:

<tool:LongListSelector x:Name="citiesListGropus" Background="Transparent" 
   ItemTemplate="{StaticResource citiesItemTemplate}"                    
   GroupHeaderTemplate="{StaticResource groupHeaderTemplate}" 
   GroupItemTemplate="{StaticResource groupItemTemplate}" Height="468" Margin="0,68,0,0">
      <tool:LongListSelector.GroupItemsPanel>
         <ItemsPanelTemplate>
            <tool:WrapPanel/>
         </ItemsPanelTemplate>
      </tool:LongListSelector.GroupItemsPanel>
</tool:LongListSelector>  

还有一个DataTemplate

<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
   <Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName">
      <TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
   </Border>
</DataTemplate>

如何更改 Border 中的 Visibility 属性 DataTemplate ?我想隐藏DataTemplate。但是我无法将我的数据绑定到TextBlock Text="{Binding Title}"这样的属性,因为我做了一次绑定数据,然后我需要在数据绑定后更改一些属性。

有什么想法吗?

更新 1

所以,我的主要目标是过滤城市列表。我想按名称过滤它们。

我的算法:

1) 我从WebService 获取数据。

2) 加载我的ViewModel

  if (!App.CitiesViewModel.IsDataLoaded)
     {
         App.CitiesViewModel.LoadData(serviceResponse.Result);
     }

3) 按名称对城市进行分组。我的代码如this code。 这很重要,尤其是对于LongListSeletstor,我必须使用模板。

好的,我的数据准备好了。现在我不需要网络服务。

<!-- The template for city items -->
        <DataTemplate x:Key="citiesItemTemplate">
            <StackPanel Name="PlacePanel" 
                Orientation="Horizontal" Margin="0,0,0,17" 
                Tag="{Binding Id}"  Visibility="{Binding IsVisibility}">
                <Image Height="75" Width="75" HorizontalAlignment="Left" Margin="12,0,9,0" Name="Image" Stretch="Fill" VerticalAlignment="Top" Source="{Binding Image}"/>
                <StackPanel Width="311">
                    <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>

我有TextBox,当我输入城市名称时 - 隐藏不必要的城市。我可以使用数据绑定和INotifyPropertyChanged,所以我可以隐藏城市。

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
           TextBox name = (TextBox)sender;

           foreach(var place in App.CitiesViewModel.Items
               .Where(city => (city.Name.Contains(name.Text)) && (city.IsShow == true)))
           {
               city.IsVisibility = Visibility.Visible;
           }
           foreach (var city in App.CitiesViewModel.Items
               .Where(city => !city.Name.Contains(name.Text)))
           {
               city.IsVisibility = Visibility.Collapsed;
           }
        }

但是我有一些问题,我在搜索城市时无法隐藏这个DataTemplate

<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
   <Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName">
      <TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
   </Border>
</DataTemplate>

当我输入城市名称时,我想隐藏GroupHeaderTemplate。当TextBox 失去焦点时显示GroupHeaderTemplate

我借用了这张照片here

更新 2 我的错误是我没有使用PropertyChangedEventHandler。将此添加到 GroupCity 属性并实现接口 INotifyPropertyChanged 后,我可以在数据绑定后更改属性 Data Template

private IList<Group<City>> citiesCollectionGroup;

    var cityByName = from city in App.ViewModel.Items 
group city by Convert.ToString(City.Name[0]).ToLower() 
into c orderby c.Key select new
 GroupCity<CitiesViewModel>(Convert.ToString(c.Key[0]).ToLower(), c);    
citiesCollectionGroup = cityByName.ToList();
this.citiesListGropus.ItemsSource = citiesCollectionGroup;  

public class GroupCity<T> : IEnumerable<T>, INotifyPropertyChanged
    {
        public GroupCity(string name, IEnumerable<T> items)
        {
            this.Title = name;
            this.IsVisibility = Visibility.Visible;
            this.Items = new List<T>(items);            
        }

        public override bool Equals(object obj)
        {
            GroupCity<T> that = obj as GroupCity<T>;

            return (that != null) && (this.Title.Equals(that.Title));
        }

        public string Title
        {
            get;
            set;
        }

        private Visibility _isVisibility;
        public Visibility IsVisibility
        {
            get
            {
                return _isVisibility;
            }
            set
            {
                _isVisibility = value;
                NotifyPropertyChanged("IsVisibility");
            }
        }

        public IList<T> Items
        {
            get;
            set;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return this.Items.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.Items.GetEnumerator();
        }

        #endregion
    }

Xaml 代码:

<DataTemplate x:Key="groupHeaderTemplate" x:Name="groupHeaderTemplateName">
   <Border Background="{StaticResource PhoneAccentBrush}" Width="75" Height="75" Margin="-333, 15, 0, 15" x:Name="groupHeaderName" Visibility="{Binding IsVisibility}">
      <TextBlock Text="{Binding Title}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
   </Border>
</DataTemplate>

现在我们可以更改Visibility groupHeaderTemplate。

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            foreach (GroupCity<CitiesViewModel> city in citiesCollectionGroup)
            {
                city.IsVisibility = Visibility.Collapsed;
            }
            //
        }



private void SearchText_LostFocus(object sender, RoutedEventArgs e)
        {
            foreach (GroupCity<CitiesViewModel> city in citiesCollectionGroup)
            {
                city.IsVisibility = Visibility.Visible;
            }
            //
        }

【问题讨论】:

    标签: windows-phone-7 xaml datatemplate


    【解决方案1】:

    您可以编写自己的简单 DataTemplateSelector 来执行此操作。查看this 了解更多信息。

    【讨论】:

    • 谢谢!我现在检查这篇文章。例如,我可以更改 TextBlock 的属性 Foreground。但是,我不明白,我们如何改变这一点?
    【解决方案2】:

    使用“如何更改 DataTemplate 中边框的属性可见性?我想隐藏 DataTemplate。”我了解您想根据属性更改项目的可见性,请参见下面的示例。

    (如果下面的代码不是您正在寻找的解决方案,请提供有关您要实现的目标的更多信息。重新阅读您的问题和我在此示例中得到的 cmets 我对此表示怀疑是你想做的,但我不想猜测,所以我只是回答我对你问题的解释)。

    使用绑定,您可以:

    1. 将可见性属性直接绑定到可见性类型的属性(以列表框和 Person1 为例)
    2. 将 Visibility 属性绑定到布尔属性,并使用转换器将其转换为 Visibility 类型(listbox2 和 Person2 + BoolToVis 类)。

    还有更多方法,但这是我认为最简单的两种实现方式。¨

    下面的代码结果:

    查看:

    <phone:PhoneApplicationPage 
    x:Class="VisibilityWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    xmlns:VisibilityWP="clr-namespace:VisibilityWP"
    shell:SystemTray.IsVisible="True">
    
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>
    
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.Resources>
                    <VisibilityWP:BoolToVis x:Key="BooleanToVisibilityConverter" />
            </Grid.Resources>
            <StackPanel>
                <ListBox x:Name="listBox" Height="300">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Border Width="200" Visibility="{Binding Visibility}" Background="Blue">
                                <TextBlock Text="{Binding Name}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
                            </Border>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <ListBox x:Name="listBox2" Height="300">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Border Width="200" Visibility="{Binding ShowBorder, Converter={StaticResource BooleanToVisibilityConverter}}" Background="Red">
                                <TextBlock Text="{Binding Name}" FontSize="40" Foreground="White" Margin="15, 15, 0, 0"/>
                            </Border>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
    
        </Grid>
    </Grid>
    

    后面的代码:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Data;
    namespace VisibilityWP
    {
    
        public partial class MainPage 
        {
            public MainPage()
            {
                InitializeComponent();
                DataContext = this;
                listBox.ItemsSource = new List<Person1>
                        {
                            new Person1 {Name = "Iris", Visibility = Visibility.Visible},
                            new Person1 {Name = "Somebody", Visibility = Visibility.Collapsed},
                            new Person1 {Name = "Peter", Visibility = Visibility.Visible},
    
                        };
                listBox2.ItemsSource = new List<Person2>
                        {
                            new Person2 {Name = "Iris", ShowBorder = true},
                            new Person2 {Name = "Mia", ShowBorder = true},
                            new Person2 {Name = "Somebody", ShowBorder = false}
                        };
            }
        }
    
        public class Person1
        {
            public string Name { get; set; }
            public Visibility Visibility { get; set; }
        }
        public class Person2
        {
            public string Name { get; set; }
            public bool ShowBorder { get; set; }
        }
    
        public sealed class BoolToVis : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return value is Visibility && (Visibility)value == Visibility.Visible;
            }
        }
    }
    

    【讨论】:

    • 请注意,Alexandr 可能会以这种方式看到他的列表中的空白。他可能想过滤掉一些项目。
    • @Iris 这看起来对我来说格式很好(看到你的推文)。
    • 我实际上对这个问题有点困惑,他问的是如何在运行时检索资源、过滤/分组还是可见性?我解释了他想使用绑定更改可见性属性的问题。可以这样做,但话虽如此,如果打算过滤数据,这可能不是最好的做法。
    • 感谢您的反馈,在您的允许下,我将完整地描述它的使命,我想做的事情。我的完整代码正在更新中。
    • @IrisClasson 所以,看来你是对的。但关键是对 Groups 使用 INotifyPropertyChanged。在更新 2 解决方案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    相关资源
    最近更新 更多