【问题标题】:Silverlight ItemsControl behavior: how do i get an item i click on?Silverlight ItemsControl 行为:如何获取单击的项目?
【发布时间】:2011-02-17 05:45:01
【问题描述】:

我正在为 ItemsControl 创建一个行为,目的是选择我单击的项目(并将其添加到选定项目列表中)。

所以很容易得到所有的物品:

hours = AssociatedObject.ItemsSource as List<Hour>;

当然我可以写 hours[0].Selected = true;

但是我有一个鼠标事件,我试着写这样的东西:

void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        hour = sender as Hour;
    }

问题是,它没有像我预期的那样工作......发件人不是 Hour,而是 ItemsControl。

我不知道点击了哪个小时。 那么我应该怎么做才能得到时间呢?

编辑 我的代码是这样工作的: 有一个 ItemsControl 绑定到 Days 列表。 每天都有一个小时列表。 为了表示这一点,有一个绑定到(天)小时的内部 ItemControl。 为了代表每个小时,有一个边界。

看起来像这样:

 <ItemsControl x:Name="daysPanel" Grid.Column="1" ItemsSource="{Binding Days}">
       <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ItemsControl x:Name="dayHours" ItemsSource="{Binding Hours}" Grid.Row="1">
                     <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                  <Border Name="dayHourBorder" Tag="{Binding}" Height="30" BorderBrush="#B0B6BE" Width="193" BorderThickness="1,0,1,1" Background="{Binding Path=Selected, Converter={StaticResource boolToColorConverter}}" >

【问题讨论】:

    标签: c# silverlight itemscontrol behavior


    【解决方案1】:

    感谢大家的帮助,但我找到了正确的方法。 我知道必须有一种简单的方法来获取被点击的 UI 元素,只需要一个!

    而且有! 而不是与发件人合作,你只需要这样做: e.原始来源

    这让我有了边界(以及限制在边界上的时间)。 所以它就像“简单”一样:

    (e.OriginalSource as Border).DataContext as Hour
    

    【讨论】:

    • 感谢您的提示!如果您有多个嵌套在边框中的元素,那么应该使用这个: (e.OriginalSource as FrameworkElement).DataContext as Hour; - 否则在施法时可能会出现问题。
    【解决方案2】:

    VisualTreeHelper 可能对你有用。 您可以使用在鼠标单击的地方获取所有元素并获取您的边框。它的标签绑定到 Hours,所以你可以得到它。
    来自 SO 的Get the ItemsControl of a DataTemplate 和来自http://blogs.msdn.comVisualTreeHelper 必须帮助你。

    【讨论】:

    • 谢谢,但是有一个更简单的方法,我找到了,马上贴出来
    【解决方案3】:

    我相信这应该可行 - 发送者将是发送点击事件的 UI 元素,并且由于您使用 ItemsSource 进行设置,因此每个项目的 DataContext 将是您所追求的:

    hour = (sender as FrameworkElement).DataContext as Hour
    

    【讨论】:

    • 不幸的是,这只给了我所有时间的列表,那是因为它实际上给了我一个“Day”对象。 (每天都是 24 小时的列表)。所以简而言之,这仍然没有告诉我我点击了哪个小时=/
    • 也许我错过了一些东西 - 你能说明你是如何用数据加载 ItemsControl 的吗?数据是什么类型的?
    • 我已经编辑了这个问题,希望这会让它更清楚。 Day 和 Hour 只是我创建的类,它们包含一个 DateTime 和一个名为 index 的 int。 ad Hour 得到一个名为“selected”的 DP bool
    • 因此,鉴于您指的是“AssociatedObject”——您是否使用了一些 Expression Blend 行为或其他东西?你是如何连接到点击事件的?我在您添加的 XAML 中没有看到任何事件处理程序。
    • Blend 有一些行为......但你可以编写自己的行为,这就是我所做的。注册一个事件很容易,因为你告诉行为它将使用哪个控件。那么:AssosiciatedObject.LeftMoustButtonDown += etc. 反正我自己找到了答案,你可以查看我的答案,谢谢:)
    【解决方案4】:

    ItemsControl 本身不为当前选定的项目提供任何属性或事件。您必须使用派生自 ItemsControl 和 Selector 的类,例如 ListBox,因为它包含项目选择功能(SelectedItem、SelectedIndex 属性...)。

    【讨论】:

    • 我知道,我正在自己实现它们。我的问题是如何获得被点击的 UI 元素。选择无关紧要。
    【解决方案5】:

    我不得不做一些类似于你正在做的事情。我想让当前行成为选中的行。

    最简单的方法是使用ICollectionView MSND link 并将其绑定到ItemsControl。 然后,您可以添加一个行为(如果它还没有),它会监听所选事件并相应地更改当前事件。

    那么你只需要在你的 ViewModel 上挂上CurrentChanged 事件,你就和 UI 完全解耦了 :)

    让我知道这是否是您所关注的,我可能会尝试获取我的一些代码作为示例。

    【讨论】:

    • 谢谢,但这不是我真正要做的,我在问如何获取我点击的 UI 元素,我很肯定这是可能的。
    猜你喜欢
    • 2011-01-21
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2020-05-14
    相关资源
    最近更新 更多