Я нашел несколько примеров скрытия или отображения элементов в выбранной строке во вложенной структуре 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 и обрабатывают некоторые элементы, вложенные в сетку данных. Поэтому, пожалуйста, не отмечайте это как дублирующий вопрос, потому что это не так. Я искал час и прочитал несколько примеров. Я думаю, у меня есть идея, как это работает. Я просто не могу понять, как правильно связывать. Я - Java-разработчик, это хобби-проект на C #, поэтому я учусь на примерах