无法关注ListView

时间:2016-10-11 17:38:14

标签: c# wpf xaml windows-phone-7 mvvm

情况:在MVVM模式中,我在listview上有一些输入绑定,只有在关注listview时才能工作。但是,每当用户单击时,列表视图就会失焦,用户无法执行输入绑定。

问题:我希望将重点放在listview上(按钮点击),使输入绑定工作

我尝试了什么: 我尝试使用附加属性IsFocused(我使用UIElement.Focus()和/或Keyboard.Focus()聚焦)并将其绑定到ViewModel中的bool变量,我将使用ICommand设置它。

我还尝试了一个单独的示例,我可以在后面的代码中使用System.Windows.Input.Keyboard.Focus(item)方法(我的意思是具有相同名称的.xaml.cs文件)来集中listview和有用!但是,我不知道如何在使用d:DesignInstance属性连接的ViewModel中实现类似的东西。

我相信鼠标点击事件会冒泡并在其他地方处理,这会导致列表在我点击它时立即失焦。就像,如果我找到一种方法将事件设置为有帮助的处理,但我再次不知道如何在viewmodel中执行此操作。这是我附属的财产:

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>

1 个答案:

答案 0 :(得分:-1)

您描述的焦点行为很容易从代码隐藏中实现,并且这样做不会违反MVVM模式。考虑Josh Smith的帖子,如下:

https://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097

  

在此处使用ViewModel可以更轻松地创建视图   可以显示一个Customer对象,并允许像   &#34;未选中的&#34;布尔属性的状态。它还提供了这种能力   轻松告诉客户保存其状态。如果视图受到约束   直接到Customer对象,视图需要大量的代码   使这项工作正常。在精心设计的MVVM架构中,   大多数视图的代码隐藏应为空,或者最多只包含   操纵其中包含的控件和资源的代码   视图。有时也需要在View中编写代码   与ViewModel对象交互的代码隐藏,例如挂钩   事件或调用一个本来很难的方法   从ViewModel本身调用。