0

オフィスの元に戻すドロップダウン (下の画像) のようなものを達成する方法はありますか? つまり、ユーザーが最初以外の項目にマウスを置いたときに前の項目を強調表示したいですか? FluentRibbon からいくつかの制御を試みましたが、これまでのところ運がありません..

ここに画像の説明を入力

4

2 に答える 2

2

ほとんどの場合、このようなコントロールの設計は Blend で行われます。ただし、Blend の使用方法がわからない場合でも、XAML とコード ビハインドだけで同様の結果を得ることができますが、さらに多くの作業を行う必要があります。

CustomListBoxItemから継承する というクラスを作成することから始めListBoxItemます。次に、リストボックス内のアイテムを強調表示するために使用される依存関係プロパティを定義します。

public class CustomListBoxItem : ListBoxItem
{
    public static readonly DependencyProperty IsVirtuallySelectedProperty =
       DependencyProperty.Register("IsVirtuallySelected", typeof(bool), 
                                   typeof(CustomListBoxItem),
                                   new PropertyMetadata(false));

    public CustomListBoxItem() : base()
    { }

    public bool IsVirtuallySelected
    {
        get { return (bool)GetValue(IsVirtuallySelectedProperty); }
        set { SetValue(IsVirtuallySelectedProperty, value); }
    }
}

次に、リストボックスを追加し、XAML でスタイルを定義します。

<ListBox Name="listBox" MouseMove="listBox_MouseMove" SelectionChanged="listBox_SelectionChanged">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type local:CustomListBoxItem}">
                <Style.Triggers>
                    <Trigger Property="IsVirtuallySelected" Value="true">
                        <Setter Property="Background" Value="SkyBlue"/>
                    </Trigger>
                    <Trigger Property="IsVirtuallySelected" Value="false">
                        <Setter Property="Background" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
</ListBox>

whereはが定義さlocalれている名前空間です。CustomListBoxItemXAML 部分に必要なのはこれだけです。本当の魔法はコード ビハインドで発生します。

イベント ハンドラは次のlistBox_MouseMoveようになります。

private void listBox_MouseMove(object sender, MouseEventArgs e)
    {
        bool itemFound = false;

        for (int i = 0; i < listBox.Items.Count; i++)
        {
            var currentItem = listBox.ItemContainerGenerator.ContainerFromIndex(i) as CustomListBoxItem;

            if (currentItem == null) 
                continue;

            // Check whether the cursor is on an item or not.
            if (IsMouseOverItem(currentItem, e.GetPosition((IInputElement)currentItem)))
            {
                // Unselect all items before selecting the new group
                listBox.Items.Cast<CustomListBoxItem>().ToList().ForEach(x => x.IsVirtuallySelected = false);

                // Select the current item and the ones above it
                for (int j = 0; j <= listBox.Items.IndexOf(currentItem); j++)
                {
                    ((CustomListBoxItem)listBox.Items[j]).IsVirtuallySelected = true; 
                }

                itemFound = true;
                break;
            }
        }

        // If the item wasn't found for the mouse point, it means the pointer is not over any item, so unselect all.
        if (!itemFound)
        {
            listBox.Items.Cast<CustomListBoxItem>().ToList().ForEach(x => x.IsVirtuallySelected = false);
        }
    }

また、IsMouseOverItemカーソルがアイテム上にあるかどうかを判断するために使用されるヘルパー メソッドは、次のように定義されます。

 private bool IsMouseOverItem(Visual item, Point mouseOverPoint)
    {
        Rect currentDescendantBounds = VisualTreeHelper.GetDescendantBounds(item);
        return currentDescendantBounds.Contains(mouseOverPoint);
    }

最後にlistBox_SelectedChanged、ListBox のクリック ハンドラーとして機能するイベント ハンドラー:

 private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Get all the virtually selected items
        List<CustomListBoxItem> selectedItems =
            listBox.Items.Cast<CustomListBoxItem>().Where(x => x.IsVirtuallySelected).ToList();

        if (selectedItems == null || !selectedItems.Any())
            return;

        // Do something with the selected items
        DoCoolStuffWithSelectedItems();

        // Unselsect all.
        listBox.Items.Cast<CustomListBoxItem>().ToList().ForEach(x => x.IsVirtuallySelected = false);
        listBox.UnselectAll();
    }

そしてブーム、私たちは終わりました。クラス コンストラクターの ListBox にいくつかの項目を追加できるようになりました。

 public MainWindow()
    {
        InitializeComponent();


        listBox.Items.Add(new CustomListBoxItem { Content = "hello world!" });
        listBox.Items.Add(new CustomListBoxItem { Content = "wpf is cool" });
        listBox.Items.Add(new CustomListBoxItem { Content = "today is tuesday..." });
        listBox.Items.Add(new CustomListBoxItem { Content = "I like coffee" });
    }

XAML で強調表示の色としてランダムな色を使用したことに注意してください。自由に変更して試してみてください。

于 2013-07-02T18:40:16.357 に答える
1

次のようなものが必要だと思います:

<ControlTemplate TargetType="ListBoxItem">
    <TextBlock Text="{Binding LastOperation}">
        <TextBlock.Style>
            <Style TargetType="TextBlock">
                <Style.Triggers>
                    <DataTrigger>
                        <DataTrigger.Binding>
                            <MultiBinding>
                                <Binding Path="MouseOverIndex"/>
                                <Binding Path="CurrentIndex"/>
                            </MultiBinding>
                        </DataTrigger.Binding>
                        <Setter Property="Foreground" Value="Gold"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</ControlTemplate>
于 2013-07-02T16:37:06.683 に答える