WPF DataGrid在另一个DataGrid的选定行上可见

时间:2019-01-06 12:07:04

标签: c# wpf datagrid

我找到了一些示例来隐藏或显示嵌套DataGrid结构中所选行上的元素,但是我试图做一些不同的事情,并且找不到正确的绑定。

我有两个数据网格,我希望第二个仅在第一个具有选定行时可见。我喜欢使用BooleanToVisibilityConverter,因为这似乎是最干净的解决方案。

App.xaml

<Application x:Class="GalaxyCreator.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:GalaxyCreator.ViewModel"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:ignore="http://www.galasoft.ch/ignore"
             StartupUri="MainWindow.xaml"
             mc:Ignorable="d ignore">

    <Application.Resources>

        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
                <ResourceDictionary Source="ViewportControl/ViewportControlResourceDictionary.xaml"/>

            </ResourceDictionary.MergedDictionaries>

            <!--Global View Model Locator-->
            <vm:ViewModelLocator x:Key="Locator"
                             d:IsDataSource="True" />
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
        </ResourceDictionary>
    </Application.Resources>

</Application>

我的实施xaml的提取

            <Grid Grid.Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="450"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <DataGrid Name="OrderGrid" ItemsSource="{Binding Path=Job.Orders}" SelectedItem="{Binding Path=SelectedOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                          ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" 
                          ScrollViewer.HorizontalScrollBarVisibility="Auto" Height="Auto" 
                          HorizontalAlignment="Left" SelectionMode="Single" AutoGenerateColumns="False" >
                    <DataGrid.Columns>
                        <DataGridTextColumn Binding="{Binding Path=Order}" ClipboardContentBinding="{x:Null}" Header="Order"/>
                        <DataGridCheckBoxColumn Binding="{Binding Path=DefaultOrder}" ClipboardContentBinding="{x:Null}" Header="Default"/>
                    </DataGrid.Columns>
                </DataGrid>
                <DataGrid ItemsSource="{Binding Path=SelectedOrder.Parameters, Mode=TwoWay}" 
                          AutoGenerateColumns="True" MinColumnWidth="250" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" 
                          ScrollViewer.HorizontalScrollBarVisibility="Auto" Height="Auto" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,500,0"
                          Visibility="{Binding IsSelected, Source={x:Reference OrderGrid}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
            </Grid>

ViewModel

using GalaSoft.MvvmLight.Command;
using GalaxyCreator.Dialogs.DialogService;
using GalaxyCreator.Model.JobEditor;
using GalaxyCreator.Model.Json;
using System;
using System.Collections.Generic;
using System.Windows;

namespace GalaxyCreator.Dialogs.JobEditor
{
    class JobEditorDetailViewModel : DialogViewModelBase
    {
        public Job Job { get; set; }

        public ShipSize? JobCategoryShipSize
        {
            get
            {
                if(Job.JobCategory.ShipSize == null)
                {
                    return ShipSize.NONE;
                }
                return Job.JobCategory.ShipSize;
            }
            set
            {
                if(value == ShipSize.NONE)
                {
                    Job.JobCategory.ShipSize = null;
                }
                else
                {
                    Job.JobCategory.ShipSize = value;
                }                
            }
        }

        public ShipSize? ShipShipSize
        {
            get
            {
                if (Job.Ship.Size == null)
                {
                    return ShipSize.NONE;
                }
                return Job.Ship.Size;
            }
            set
            {
                if (value == ShipSize.NONE)
                {
                    Job.Ship.Size = null;
                }
                else
                {
                    Job.Ship.Size = value;
                }
            }
        }

        private RelayCommand<object> _saveCommand = null;
        public RelayCommand<object> SaveCommand
        {
            get { return _saveCommand; }
            set { _saveCommand = value; }
        }

        private RelayCommand<object> _cancelCommand = null;
        public RelayCommand<object> CancelCommand
        {
            get { return _cancelCommand; }
            set { _cancelCommand = value; }
        }

        private RelayCommand<object> _jobCategoryTagUpdateCommand = null;
        public RelayCommand<object> JobCategoryTagUpdateCommand
        {
            get
            {
                if (_jobCategoryTagUpdateCommand == null)
                {
                    _jobCategoryTagUpdateCommand = new RelayCommand<object>((param) => UpdateTagOnJobCategory(param));
                }

                return _jobCategoryTagUpdateCommand;
            }
        }

        private RelayCommand<object> _jobLocationsFactionUpdateCommand = null;
        public RelayCommand<object> JobLocationFactionsUpdateCommand
        {
            get
            {
                if (_jobLocationsFactionUpdateCommand == null)
                {
                    _jobLocationsFactionUpdateCommand = new RelayCommand<object>((param) => UpdateLocationsOnJobLocation(param));
                }

                return _jobLocationsFactionUpdateCommand;
            }
        }

        private RelayCommand<object> _shipFactionsTagUpdateCommand = null;
        public RelayCommand<object> ShipFactionsUpdateCommand
        {
            get
            {
                if (_shipFactionsTagUpdateCommand == null)
                {
                    _shipFactionsTagUpdateCommand = new RelayCommand<object>((param) => UpdateFactionsOnShip(param));
                }

                return _shipFactionsTagUpdateCommand;
            }
        }

        private RelayCommand<object> _shipTagsUpdateCommand = null;
        public RelayCommand<object> ShipTagsUpdateCommand
        {
            get
            {
                if (_shipTagsUpdateCommand == null)
                {
                    _shipTagsUpdateCommand = new RelayCommand<object>((param) => UpdateTagsOnShip(param));
                }

                return _shipTagsUpdateCommand;
            }
        }

        private JobOrder _selectedOrder;
        public JobOrder SelectedOrder
        {
            get { return _selectedOrder; }
            set
            {
                Set(ref _selectedOrder, value);
            }
        }

        public String JobCategoryTags
        {
            get
            {
                if(this.Job.JobCategory.Tags != null)
                {
                    string Result = "{";
                    foreach (Tag Tag in this.Job.JobCategory.Tags)
                    {
                        Result = Result + " " + Tag.ToString() + " ";
                    }
                    Result = Result + "}";
                    return Result;
                }
                return "";
            }
        }

        public String ShipTags
        {
            get
            {
                if(this.Job.Ship.Tags != null)
                {
                    string Result = "{";
                    foreach (Tag Tag in this.Job.Ship.Tags)
                    {
                        Result = Result + " " + Tag.ToString() + " ";
                    }
                    Result = Result + "}";
                    return Result;
                }
                return "";
            }
        }

        public String JobLocationFactions
        {
            get
            {
                if(this.Job.JobLocation.Factions != null)
                {
                    string Result = "{";
                    foreach (Faction Faction in this.Job.JobLocation.Factions)
                    {
                        Result = Result + " " + Faction.ToString() + " ";
                    }
                    Result = Result + "}";
                    return Result;
                }
                return "";
            }
        }

        public String ShipFactions
        {
            get
            {
                if(this.Job.Ship.Factions != null)
                {
                    string Result = "{";
                    foreach (Faction Faction in this.Job.Ship.Factions)
                    {
                        Result = Result + " " + Faction.ToString() + " ";
                    }
                    Result = Result + "}";
                    return Result;
                }
                return "";
            }
        }

        private IList<SubordinateItem> _subordinateItems = new List<SubordinateItem>();
        public IList<SubordinateItem> SubordinateItems
        {
            get { return _subordinateItems; }
            set
            {
                Set(ref _subordinateItems, value);
            }
        }

        public JobEditorDetailViewModel(string message, Job job) : base(message)
        {
            this.Job = job;
            this._saveCommand = new RelayCommand<object>((parent) => OnSaveClicked(parent));
            this._cancelCommand = new RelayCommand<object>((parent) => OnCancelClicked(parent));
            foreach (String subordinate in Job.Subordinates)
            {
                _subordinateItems.Add(new SubordinateItem(subordinate));
            }
        }

        private void OnSaveClicked(object parameter)
        {
            this.Job.Subordinates.Clear();
            foreach (SubordinateItem item in _subordinateItems)
            {
                this.Job.Subordinates.Add(item.Value);
            }
            this.CloseDialogWithResult(parameter as Window, DialogResult.Yes);
        }

        private void OnCancelClicked(object parameter)
        {
            this.CloseDialogWithResult(parameter as Window, DialogResult.No);
        }

        private void UpdateTagOnJobCategory(object param)
        {
            if(param != null)
            {
                Tag tagParam = (Tag)param;
                if (Job.JobCategory.Tags.Contains(tagParam))
                {
                    Job.JobCategory.Tags.Remove(tagParam);
                }
                else
                {
                    Job.JobCategory.Tags.Add(tagParam);
                }
                RaisePropertyChanged("JobCategoryTags");
            }
        }

        private void UpdateLocationsOnJobLocation(object param)
        {
            if (param != null)
            {
                Faction factionParam = (Faction)param;
                if (Job.JobLocation.Factions.Contains(factionParam))
                {
                    Job.JobLocation.Factions.Remove(factionParam);
                }
                else
                {
                    Job.JobLocation.Factions.Add(factionParam);
                }
                RaisePropertyChanged("JobLocationFactions");
            }
        }

        private void UpdateFactionsOnShip(object param)
        {
            if (param != null)
            {
                Faction factionParam = (Faction)param;
                if (Job.Ship.Factions.Contains(factionParam))
                {
                    Job.Ship.Factions.Remove(factionParam);
                }
                else
                {
                    Job.Ship.Factions.Add(factionParam);
                }
                RaisePropertyChanged("ShipFactions");
            }
        }

        private void UpdateTagsOnShip(object param)
        {
            if (param != null)
            {
                Tag tagParam = (Tag)param;
                if (Job.Ship.Tags.Contains(tagParam))
                {
                    Job.Ship.Tags.Remove(tagParam);
                }
                else
                {
                    Job.Ship.Tags.Add(tagParam);
                }
                RaisePropertyChanged("ShipTags");
            }
        }

    }
}

我希望隐藏第二个数据网格,直到我单击第一个数据网格中的一行,设置了SelectedItem并希望第二个数据网格显示自己。此刻第二个数据网格永远不会显示并保持隐藏状态。

我看过的所有示例现在都使用RelativeSource并处理嵌套在datagrid中的某些元素。因此,请勿将其标记为重复问题,因为事实并非如此。我一直在寻找一个小时,并阅读了一些示例。我想我知道它是如何工作的,只是无法正确绑定,我是一个Java开发人员,这是C#中的一个业余项目,所以我通过示例进行学习

1 个答案:

答案 0 :(得分:0)

我设法弄清楚了,对我来说不清楚的是,即使它不是相同的组件类型,也可以提升层次结构。因此,我可以转到Grid,然后再次返回到适当的DataGrid。一旦我知道这很简单

<Grid Grid.Row="0">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="450"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Label Content="Order information" Grid.Column="0" />
    <Label Content="Parameters" Grid.Column="1" />
    <DataGrid Name="OrderGrid" ItemsSource="{Binding Path=Job.Orders}" SelectedItem="{Binding Path=SelectedOrder, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
              ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" 
              ScrollViewer.HorizontalScrollBarVisibility="Auto" Height="Auto" 
              HorizontalAlignment="Left" SelectionMode="Single" AutoGenerateColumns="False" 
              Grid.Row="1">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Order}" ClipboardContentBinding="{x:Null}" Header="Order"/>
            <DataGridCheckBoxColumn Binding="{Binding Path=DefaultOrder}" ClipboardContentBinding="{x:Null}" Header="Default"/>
        </DataGrid.Columns>
    </DataGrid>
    <DataGrid ItemsSource="{Binding Path=SelectedOrder.Parameters, Mode=TwoWay}" 
              AutoGenerateColumns="True" MinColumnWidth="250" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" 
              ScrollViewer.HorizontalScrollBarVisibility="Auto" Height="Auto" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,500,0"
              Visibility="{Binding 
                  RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}}, 
                  Path=OrderGrid, 
                  Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>