Reputation: 23
I'm having trouble making ListBox
elements stay always visible.
I have ListBox
where you can select DataGrid
. Displayed name is binded to DataGrid
Tag
. Selected DataGrid
is displayed below. DataGrid
names, or rather its Tag
is binded to an array from Content
class. The problem is that ListBox
elements are not visible until you select them, and when you do, only selected item's name is displayed.
When I select second element, first one is no longer displayed and vice versa.
here is my code:
XAML:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="525">
<Window.Resources>
<col:ArrayList x:Key="dataGridDef">
<DataGrid Name="DG1" ItemsSource="{Binding Path=List1}" AutoGenerateColumns="False"
Tag="{Binding Path=GridNames[0]}">
<DataGrid.Columns>
<DataGridTextColumn Header="Grid1Name1" Binding="{Binding Path=Name1}"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid Name="DG2" ItemsSource="{Binding Path=List2}" AutoGenerateColumns="False"
Tag="{Binding Path=GridNames[1]}">
<DataGrid.Columns>
<DataGridTextColumn Header="Grid2Name1" Binding="{Binding Path=Name1}"/>
</DataGrid.Columns>
</DataGrid>
</col:ArrayList>
</Window.Resources>
<StackPanel>
<ListBox x:Name="lb" ItemsSource="{StaticResource dataGridDef}" DisplayMemberPath="Tag"
SelectedValue="{Binding Path=SelectedGrid}"/>
<ContentControl Content="{Binding ElementName=lb, Path=SelectedItem}"/>
<TextBlock Height="100" Text="{Binding Path=Str.Header}"/>
<TextBlock Text="{Binding Path=SelectedGrid.Tag}"/>
</StackPanel>
</Window>
C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Content();
}
}
public class Content
{
public ObservableCollection<Asd> List1 { get; set; }
public ObservableCollection<Asd> List2 { get; set; }
public DataGrid SelectedGrid { get; set; }
private string[] _gridName;
public string[] GridNames { get { return _gridName; } }
public Content()
{
List1 = new ObservableCollection<Asd>();
List2 = new ObservableCollection<Asd>();
List1.Add(new Asd { Name1 = "1" });
List1.Add(new Asd { Name1 = "2" });
List2.Add(new Asd { Name1 = "a" });
List2.Add(new Asd { Name1 = "b" });
_gridName = new string[] { "G1", "G2" };
}
}
public class Asd: INotifyPropertyChanged
{
private string _name1;
public string Name1
{
get { return _name1; }
set
{
if (value == _name1) return;
_name1 = value;
OnPropertyChanged(nameof(Name1));
}
}
public event PropertyChangedEventHandler PropertyChanged;
internal void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 2
Views: 4052
Reputation: 12906
You can fix the issue by defining binding source for your resource.
Define your datagrids' bindings so that their source is MyWindow:
Tag="{Binding Path=DataContext.GridNames[0], Source={x:Reference MyWindow}}"
Result:
<Window x:Class="WpfApp6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp6"
xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" x:Name="MyWindow">
<Window.Resources>
<collections:ArrayList x:Key="dataGridDef">
<DataGrid Name="DG1" ItemsSource="{Binding Path=List1}" AutoGenerateColumns="False" Tag="{Binding Path=DataContext.GridNames[0], Source={x:Reference MyWindow}}">
<DataGrid.Columns>
<DataGridTextColumn Header="Grid1Name1" Binding="{Binding Path=Name1}"/>
</DataGrid.Columns>
</DataGrid>
<DataGrid Name="DG2" ItemsSource="{Binding Path=List2}" AutoGenerateColumns="False" Tag="{Binding Path=DataContext.GridNames[1], Source={x:Reference MyWindow}}">
<DataGrid.Columns>
<DataGridTextColumn Header="Grid2Name1" Binding="{Binding Path=Name1}"/>
</DataGrid.Columns>
</DataGrid>
</collections:ArrayList>
</Window.Resources>
<StackPanel>
<ListBox x:Name="lb" ItemsSource="{StaticResource dataGridDef}" DisplayMemberPath="Tag" SelectedValue="{Binding Path=SelectedGrid, Mode=TwoWay}"/>
<ContentControl Content="{Binding ElementName=lb, Path=SelectedItem}"/>
<TextBlock Height="100" Text="{Binding Path=Str.Header}"/>
<TextBlock Text="{Binding Path=SelectedGrid.Tag}"/>
</StackPanel>
Upvotes: 6