WPF 绑定到资源中的元素
Posted
技术标签:
【中文标题】WPF 绑定到资源中的元素【英文标题】:WPF binding to elements in resources 【发布时间】:2018-07-18 16:12:48 【问题描述】:我无法让 ListBox
元素始终可见。
我有ListBox
,您可以在其中选择DataGrid
。显示的名称绑定到 DataGrid
Tag
。选中的DataGrid
显示在下方。 DataGrid
名称,或者更确切地说,它的 Tag
绑定到来自 Content
类的数组。问题是 ListBox
元素在您选择它们之前是不可见的,当您选择它们时,只会显示所选项目的名称。
当我选择第二个元素时,第一个元素不再显示,反之亦然。
这是我的代码:
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));
【问题讨论】:
【参考方案1】:您可以通过定义binding source for your resource 来解决此问题。
-
为您的窗口命名。例如 x:Name=MyWindow。
定义数据网格的绑定,使其源为 MyWindow:
Tag="Binding Path=DataContext.GridNames[0], Source=x:Reference MyWindow"
结果:
这是完整的 XAML:
<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>
【讨论】:
以上是关于WPF 绑定到资源中的元素的主要内容,如果未能解决你的问题,请参考以下文章