【问题标题】:ListBox items return string, when DataTemplate is Button当 DataTemplate 为 Button 时,ListBox 项返回字符串
【发布时间】:2016-03-11 03:12:02
【问题描述】:

我正在创建一个 WP 8.1 Silverlight 应用程序。

我有一个字符串名称的ObservableCollection,它设置为ListBoxItemsSource。哪些是ListBox 中的按钮名称。然后我想从ListBox 中提取按钮,但返回值是string 类型。

xaml 代码为:

<ListBox x:Name="Game_ScrollViewer_online" Margin="41,104,128,6" SelectedValuePath="Current_game_button">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button x:Name="Current_game_button" Content="{Binding}" 
                    HorizontalAlignment="Center" Height="80" Margin="-14,6,-15,0"
                    VerticalAlignment="Top" Width="210" Template="{StaticResource Button_CurrentLayout1}" 
                    RenderTransformOrigin="0.5,0.5" Foreground="#FFCBECCB" FontFamily="Times New Roman"
                    Click="LoadGame_online" FontSize="16">
            </Button>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

然后我想提取按钮元素:

for (int i = 0; i < Game_ScrollViewer_online.Items.Count; i++)
{
     var tempType = Game_ScrollViewer_online.Items[i].GetType();
     Button tempBut = (Game_ScrollViewer_online.Items[i] as Button); 
     //Do stuff with button
}

但如前所述,返回类型是字符串。

为什么不是按钮?有没有办法访问该按钮?

【问题讨论】:

    标签: c# wpf xaml listbox windows-phone-8.1


    【解决方案1】:

    为此您需要FrameworkTemplate.FindName Method (String, FrameworkElement)

    private childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
    {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
    }
    

    然后:

    for (int i = 0; i < Game_ScrollViewer_online.Items.Count; i++)
    {
         ListBoxItem GameListBoxItem = (ListBoxItem)(Game_ScrollViewer_online.ItemContainerGenerator.ContainerFromIndex(i));
         ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(GameListBoxItem);
         DataTemplate myDataTemplate = contentPresenter.ContentTemplate;
         Button tempBut = (Button) myDataTemplate.FindName("Current_game_button", contentPresenter);
         //Do stuff with button
    }
    

    要解决缺少的FindName,请像这样使用FindDescendant

    public T FindDescendant<T>(DependencyObject obj) where T : DependencyObject
    {
        if (obj is T)
            return obj as T;
    
        int childrenCount = VisualTreeHelper.GetChildrenCount(obj);
        if (childrenCount < 1)
            return null;
    
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child is T)
                return child as T;
        }
    
        for (int i = 0; i < childrenCount; i++)
        {
            DependencyObject child = FindDescendant<T>(VisualTreeHelper.GetChild(obj, i));
            if (child != null && child is T)
                return child as T;
        }
    
        return null;
    }
    

    【讨论】:

    • 太棒了,效果很好!像您一样提取列表项然后仅使用FindDescendant 它可以工作。更新您的答案,我会将其标记为已解决:)
    猜你喜欢
    • 2016-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多