簡體   English   中英

無法聚焦ListView

[英]Unable to focus ListView

情況:在MVVM模式中,我在listview上有一些輸入綁定,僅當listview聚焦時才起作用。 但是,每當用戶單擊時,列表視圖就會失去焦點,並且用戶將無法執行輸入綁定。

問題: 我想通過inputbindings起作用的方式將焦點集中在listview上(單擊按鈕時)

我嘗試的方法:我嘗試使用附加屬性IsFocused(在這里我使用UIElement.Focus()和/或Keyboard.Focus()進行聚焦)並將其綁定到ViewModel中的bool變量,該變量將使用ICommand進行設置。

我還嘗試了一個單獨的示例,在該示例中,可以在后面的代碼(我的意思是具有相同名稱的.xaml.cs文件)中使用System.Windows.Input.Keyboard.Focus(item)方法來聚焦列表視圖,並且它可以正常工作! 但是,我不知道如何在使用ad:DesignInstance屬性連接的ViewModel中實現類似的操作。

我相信mouseclick事件會冒泡並在其他地方處理,這會導致列表在我單擊后就失去焦點。 就像,如果我找到一種將事件設置為已處理的方法會有所幫助,但是同樣,我也不知道如何在視圖模型中執行此操作。 這是我的附屬財產:

FocusExtension.cs

public static class FocusExtension {
    public static bool GetIsFocused(DependencyObject obj) {
        return (bool)obj.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject obj, bool value) {
        obj.SetValue(IsFocusedProperty, value);
    }

    public static readonly DependencyProperty IsFocusedProperty =
        DependencyProperty.RegisterAttached(
            "IsFocused", typeof(bool), typeof(FocusExtension),
            new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));

    private static void OnIsFocusedPropertyChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e) {
        var uie = (UIElement)d;
        if ((bool)e.NewValue) {
            uie.Focus();
        }
    }
}

XAML文件:

    <ListView
        x:Name="lv"
        Grid.Column="2" Margin="2" MinWidth="250" Height="400" ToolTip="the List"
        HorizontalContentAlignment="Stretch"
        ItemsSource="{Binding ListBindingInVM}"
        ScrollViewer.HorizontalScrollBarVisibility="Auto"
        ScrollViewer.CanContentScroll="False"
        dd:DragDrop.IsDragSource="True"
        dd:DragDrop.IsDropTarget="True"
        dd:DragDrop.DropHandler="{Binding }"
        behaviour:ListViewAutoScroll.AutoScrollToEnd="True"
        ScrollViewer.VerticalScrollBarVisibility="Visible"
        >

        <ListView.Style>
            <Style TargetType="ListView" >
                <Setter Property="ViewModels:FocusExtension.IsFocused" Value="{Binding ListFocused, Mode=TwoWay}"></Setter>
              <!--The one below is not clean, but worked. However, list goes out of focus on click. -->
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="ViewModels:FocusExtension.IsFocused" Value="True"></Setter>
                    </Trigger>
                </Style.Triggers>


            </Style>
        </ListView.Style>

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDown">
            <!--This command sets the ListFocused to true-->
                <i:InvokeCommandAction Command="{Binding BringListToFocus }"></i:InvokeCommandAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>


        <ListView.InputBindings>
            <!-- Bindings that don't work when list is not focused-->
            <KeyBinding Modifiers="Control" Key="C" Command="{Binding CopyCommand}"/>
            <KeyBinding Modifiers="Control" Key="V" Command="{Binding PasteCommand}"/>
        </ListView.InputBindings>

        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Copy" Command= "{Binding CopyCommand}"></MenuItem>
                <MenuItem Header="Paste" Command= "{Binding PasteCommand}"></MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>

您所描述的焦點行為很容易從背后的代碼中實現,並且這樣做不會違反MVVM模式。 考慮下面的喬什·史密斯的帖子:

https://msdn.microsoft.com/zh-CN/magazine/dd419663.aspx#id0090097

在這里使用ViewModel可以更輕松地創建一個視圖,該視圖可以顯示Customer對象,並允許諸如Boolean屬性的“未選擇”狀態之類的事情。 它還提供了輕松告知客戶保存其狀態的功能。 如果視圖直接綁定到Customer對象,則該視圖將需要大量代碼才能使其正常工作。 在設計良好的MVVM體系結構中,大多數視圖的背后代碼應為空,或者最多只能包含操縱該視圖中包含的控件和資源的代碼。 有時也有必要在與ViewModel對象進行交互的View的代碼隱藏中編寫代碼,例如,鈎住事件或調用否則很難從ViewModel本身調用的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM