单击文本块时隐藏兄弟列表框

时间:2014-02-01 00:24:28

标签: c# wpf silverlight xaml windows-phone

我很奇怪是否有人知道如何在单击兄弟时更改DataTemplate中列表框的可见性。 DataTemplate正在列表框中使用。以下是我正在使用的xaml的示例:

 <DataTemplate x:Key="Template1">

                <StackPanel Margin="110,0,0,0">
                    <TextBlock Text="{Binding Name}" />
                    <TextBlock Name="ShowHide" Text="Hide" Tap="ShowHide_Tap" />
                    <ListBox Name="Listbox1" ItemsSource="{Binding SecondList}" Visibility="Visible" ItemTemplate="{StaticResource Template2}"/>
                </StackPanel>

        </DataTemplate>

以下是我的尝试,但我不能使用FindName

 private void ShowHide_Click(object sender, System.Windows.Input.GestureEventArgs e)
    {


        var item = sender as TextBlock;
        ListBox Listbox = null;
        if (item != null)
        {

            ContentPresenter templateParent = GetFrameworkElementByName<ContentPresenter>(item);

            DataTemplate dataTemplate = templateParent.ContentTemplate;
            if (dataTemplate != null && templateParent != null)
            {
               Listbox = templateParent.FindName("Listbox1") as ListBox;
           }
            if (Listbox != null)
            {
                MessageBox.Show(String.Format("ERROR!"));
            }
            else
                Listbox.Visibility = Visibility.Collapsed;
        }


}

        private static T GetFrameworkElementByName<T>(FrameworkElement referenceElement) where T : FrameworkElement
        {
            FrameworkElement child = null;
            for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceElement); i++)
            {
                child = VisualTreeHelper.GetChild(referenceElement, i) as FrameworkElement;
                System.Diagnostics.Debug.WriteLine(child);
                if (child != null && child.GetType() == typeof(T))
                { break; }
                else if (child != null)
                {
                    child = GetFrameworkElementByName<T>(child);
                    if (child != null && child.GetType() == typeof(T))
                    {
                        break;
                    }
                }
            }
            return child as T;
        }

如果任何人有任何见解,他们将不胜感激,

感谢。

2 个答案:

答案 0 :(得分:0)

欢迎使用StackOverflow!

一般来说,这不是使用WPF的方法,特别是如果您使用的是DataTemplates。 WPF中视图的目的是显示视图模型并触发用户事件,仅此而已。通过在运行时更改数据模板,您可以有效地将视图状态存储在视图本身中。这完全违背了WPF的设计使用方式。

要正确执行此操作,您的视图模型(即具有SecondList属性的类)应该有一个名为ListBoxVisibility的额外属性,您可以将列表框的Visibility成员绑定到该属性。更简洁的方法是使用bool,然后在视图中使用转换器将其从bool类型转换为Visibility类型。无论哪种方式,视图模型还应具有ICommand类型的属性(例如OnButtonPressedCommand),当用户按下该按钮时,该按钮会调用该属性。 OnButtonPressedCommand的处理程序(也应该在视图模型中)然后将ListBoxVisible或其他任何值设置为您想要的值,然后传播到列表框。以这种方式做事可以很好地分离关注点,这意味着可以创建视图模型并独立测试其可见性改变行为单元,而无需自己创建视图。

答案 1 :(得分:0)

Blend SDK恰好为此提供了功能 - 您甚至可以只使用XAML,不需要代码。只需使用EventTrigger(在“点击”事件中)和ChangePropertyAction。这是它的外观:

<TextBlock Name="ShowHide" Text="Hide" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Tap">
            <ei:ChangePropertyAction TargetName="Listbox1" 
                PropertyName="Visibility" Value="Collapsed" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBlock>
<ListBox Name="Listbox1" ItemsSource="{Binding SecondList}" Visibility="Visible" />

请注意,这需要您添加对以下扩展的引用:

  • System.Windows.Interactivity
  • Microsoft.Expression.Interactions

使用命名空间在XAML中引用它们:

  • xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  • xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"