【问题标题】:WPF Xaml passing Control in attributeWPF Xaml 在属性中传递 Control
【发布时间】:2011-07-21 14:03:46
【问题描述】:

我有一个 TextBox(称为 SearchBox)和一个 ListView(称为 EmployeeList)。 TextBox 的 TextChanged 事件在 ListView 中显示搜索结果。这一切都很好,但我需要一些额外的功能,我想捕获 KeyUp/Down 事件以浏览 ListView 元素。我知道我可以为 KeyUp/Down 事件添加一个处理程序并完成,但这是我将经常使用的东西,所以我想要一些可重复使用的东西。

这是我尝试做的,我创建了一个静态类(称为 SearchBoxHelper)并添加了一个可附加属性。现在我要做的是通过 xaml 传递对 ListView 控件(不是其中一个属性)的引用作为可附加依赖项属性的值。

/Controls/SearchBoxHelper.cs

public static class SearchBoxHelper
{
    public static readonly DependencyProperty HelpsListView = DependencyProperty.RegisterAttached("HelpsListView", typeof(ListView), typeof(SearchBoxHelper), new PropertyMetadata(null, OnHelpsListViewChanged));

    private static void OnHelpsListViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ListView listview = d as ListView;

        // this is where it crashes, because the d is not of type ListView
        MessageBox.Show(listview.Name);
    }

    public static ListView GetHelpsListView(DependencyObject d)
    {
        return d.GetValue(HelpsListView) as ListView;
    }

    public static void SetHelpsListView(DependencyObject d, ListView listview)
    {
        d.SetValue(HelpsListView, listview);
    }

}

/Pages/EmployeesPage.xaml

<control:NavPage x:Class="DtcInvoicer.Pages.EmployeesPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:control="clr-namespace:DtcInvoicer.Controls"
             x:Name="Page" Width="950" Height="580"
             Loaded="Page_Loaded">

    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="350" />
            <ColumnDefinition Width="260" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Row="0" Grid.Column="0">
            <TextBlock FontSize="22" FontWeight="SemiBold" Text="Employees" />
        </StackPanel>
        <StackPanel Grid.Row="1" Grid.Column="0">
            <control:PolygonContainer Points="0,0 330,0 340,10 350,30 0,30" Background="{StaticResource Gradient_Black}">
                <WrapPanel>
                    <TextBox x:Name="SearchBox" TextChanged="SearchBox_TextChanged" control:SearchBoxHelper.HelpsListView="{x:Reference Name=EmployeeList}" Margin="5" Width="300" Height="20" BorderThickness="0" Background="#30FFFFFF" Foreground="White" />
                    <Image Width="18" Source="/Images/Icons/Search.png" />
                </WrapPanel>
            </control:PolygonContainer>
            <Border Height="490" CornerRadius="0,0,5,5" Background="{StaticResource Gradient_Blue}">
                <StackPanel>
                    <control:FxListView x:Name="EmployeeList" ItemDoubleClick="EmployeeList_ItemDoubleClick"  Height="455" BorderThickness="0" Background="Transparent" ItemContainerStyle="{StaticResource FxListViewItemContainer_Style}" ItemTemplate="{StaticResource Employee_ListViewItem_Template}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
                    <WrapPanel Height="30" />
                </StackPanel>
            </Border>
        </StackPanel>
        <StackPanel Margin="10,0,0,0" Grid.Row="1" Grid.Column="1">
            <control:PolygonContainer Points="250,0 20,0 10,10 0,30 250,30" Background="{StaticResource Gradient_Black}">
                <TextBlock Margin="0,0,5,0" Text="Open Employees" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Center" />
            </control:PolygonContainer>
            <Border Height="180" CornerRadius="0,0,5,5" Background="{StaticResource Gradient_Blue}">
                <control:FxListView x:Name="OpenEmployeesList" ItemDoubleClick="OpenEmployeesList_ItemDoubleClick" Height="160" VerticalAlignment="Top" BorderThickness="0" Background="Transparent" ItemContainerStyle="{StaticResource FxListViewItemContainer_Style}" ItemTemplate="{StaticResource EmployeePage_ListViewItem_Template}" />
            </Border>
        </StackPanel>
    </Grid>
</control:NavPage>

【问题讨论】:

  • 那发生了什么?您的 MessageBox 是否没有以 ListBox 的名称出现?
  • 不确定在控件之间传递控件是否是个好主意:)。最好使用事件冒泡/隧道来处理它或控件是自包含的一些命令操作系统
  • @user164184 是的,MessageBox 没有以 ListView 的名称出现(我得到的对象未设置为对象异常的实例)。
  • 哦,废话,刚刚想通了。我试图转换属性附加到 ListView 的 DependencyObject,但它实际上是一个 TextBox。我应该一直在做 ListView = e.NewValue as ListView;

标签: c# wpf wpf-controls binding


【解决方案1】:

想出来了...对于其他可能需要这个的人..

private static void OnHelpsListViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // ListView listview = d as ListView;

    // the propblem was with the line above, I was trying to convert the 
    // DependencyObject to a ListView and it's actually a TextBox, I should 
    // have been converting the new value of the DependencyProperty

    TextBox box = d as TextBox;
    ListView list = e.NewValue as ListView;
    if(box == null || list == null) return;

    box.PreviewKeyDown += delegate(object sender, KeyEventArgs e2)
    {
        if (e2.Key == Key.Down)
            list.SelectedIndex += (list.SelectedIndex + 1 < list.Items.Count) ? 1 : 0;
        else if (e2.Key == Key.Up)
            list.SelectedIndex -= (list.SelectedIndex - 1 >= 0) ? 1 : 0;
        else if (e2.Key == Key.Enter && list.SelectedIndex >= 0)
        { 
            // do something for the enter key 
        }
    };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2010-11-19
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多