如何在DataTemplate中获得控制权?

时间:2013-02-19 13:28:55

标签: windows-phone-7 xaml datatemplate

所以,我有一个代码:

<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>

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

任何想法?

更新1

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

我的算法:

1)我从WebService获取数据。

2)加载我的ViewModel

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

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

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

<!-- 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失去焦点时显示GroupHeaderTemplateenter image description here

我借了这张照片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;
            }
            //
        }

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

使用“我如何在DataTemplate中更改属性的可见性?我想隐藏DataTemplate。”我知道您想要根据属性更改项目的可见性,请参阅下面的示例。

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

使用绑定,您可以:

  1. 将visibility属性直接绑定到Visibility类型的属性(带有listbox和Person1的示例)
  2. 将Visibility属性绑定到布尔属性,并使用转换器将其转换为Visibility类型(listbox2和Person2 + BoolToVis类)。
  3. 还有更多方法,但在我看来,这是最容易实现的两种方式。

    以下代码的结果: screen shot of VS

    查看:

    <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;
            }
        }
    }