【问题标题】:How to bind grid to selected tree view item in WPF如何将网格绑定到 WPF 中选定的树视图项
【发布时间】:2017-07-13 23:34:08
【问题描述】:

如何在 WPF 中将网格绑定到选定的树视图项?简而言之,当我的应用程序的用户单击树视图项时,我想运行将加载一些数据并将其呈现在网格上的命令。根据项目的基础类型,我想绑定到不同的命令。

XAML

<TreeView ItemsSource="{Binding Path=SomeCollection, UpdateSourceTrigger=PropertyChanged}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=., Converter={StaticResource GetElementTypeConverter}}" Value="{x:Type Models:SomeType}">
                    // WHAT CODE GOES HERE?
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=., Converter={StaticResource GetElementTypeConverter}}" Value="{x:Type Models:SomeOtherType}">
                    // WHAT CODE GOES HERE?
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

我想以 MVVM 方式处理点击事件。

【问题讨论】:

    标签: c# wpf mvvm mvvm-light


    【解决方案1】:

    在 WPF 中,我们通过定义不同的DataTemplates 来处理不同的数据类型。在您的情况下,您可能已经定义了一些。如果没有,现在就这样做,并且在这些DataTemplates 中,您可以设置相关的ICommands。您可以通过多种方式执行此操作,但一种简单的方法是在“空白”Button 中定义您的内容:

    <DataTemplate DataType="{x:Type YourDataTypePrefix:YourDataType}">
        <Button Command="{Binding SomeCommand}">
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <!-- Define your YourDataType item content here -->
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </DataTemplate>
    <DataTemplate DataType="{x:Type YourDataTypePrefix:OtherDataType}">
        <Button Command="{Binding SomeOtherCommand}">
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <!-- Define your OtherDataType item content here -->
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </DataTemplate>
    

    更新>>>

    你说不能用Button 选择TreeViewItem,这似乎很奇怪。但是,您可以尝试使用 ToggleButton 来绑定到 TreeViewItem.IsSelected 属性:

    <ToggleButton Command="{Binding SomeCommand}" IsChecked="{Binding IsSelected, 
        RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}">
        <ToggleButton.Template>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <!-- Define your YourDataType item content here -->
                </Grid>
            </ControlTemplate>
        </ToggleButton.Template>
    </ToggleButton>
    

    如果这仍然不起作用,则使用AttachedProperty 处理DataTemplates 中Grid 上的PreviewMouseDown 事件。你可以找到很多关于使用AttachedPropertys 处理事件的在线文档,所以我在这里不再赘述。但是,如果你这样做了(这是更好的解决方案),那么你可以这样做:

    <DataTemplate DataType="{x:Type YourDataTypePrefix:YourDataType}">
        <Grid Attached:MouseEvents.PreviewMouseDown="{Binding SomeCommand}">
            <!-- Define your YourDataType item content here -->
        </Grid>
    </DataTemplate>
    

    【讨论】:

    • 这个答案看起来不错,但我有一个问题 - 现在我的 TreeViewItem 不可选择(当我点击它时,它周围没有蓝色矩形)...
    • 我想你误解了我的意思——说我的TreeViewItem 不可选择我的意思只是我在括号中所说的——TreeViewItem 周围没有蓝色(或任何其他)选择。除此之外一切正常 - 这意味着该命令已运行。
    • 你想看蓝色的选择颜色吗?如果您确实想看到它,请尝试将 Margin 添加到 Button
    • 我想看看 :)。如果我给它添加一个Margin,它会有蓝色边框吗?但我希望它看起来像任何其他选定的 TreeViewItem - 并且默认外观不是蓝色边框 - 选中时整个项目都是蓝色的。
    • 如果它对你不起作用,那么尝试使用Attached Property 处理MouseDown(或类似)事件的路线......无论如何,这是更好的选择。在 Stack Overflow 上查看我对 WPF Textbox bind with string data type property should accept only numeric value 问题的回答。我展示了如何为TextBox 创建一个Attached Property。您可以轻松地将其调整为处理 UIElement 类和鼠标事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多