在运行时绑定 属性
Binding Property at runtime
我已经在我的程序中创建了一个 UserControl 以实现可重用性:
GroupPanel.xaml:
<UserControl x:Class="View.UserControls.GroupPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"assembly=ViewModel"
Name="root">
<DockPanel>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="True"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
DataContext="{Binding ElementName=root}"
ItemsSource="{Binding DataGridItemSource}"
Name="mainGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Nr/Unit"
Binding="{Binding Nr}" />
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
和一个依赖项 属性 来设置 DataGrid 的 ItemsSource:
GroupPanel.xaml.cs:
public static readonly DependencyProperty DataGridItemSourceProperty =
DependencyProperty.Register("DataGridItemSource", typeof(IEnumerable), typeof(GroupPanel),
new PropertyMetadata(null));
public IEnumerable DataGridItemSource
{
get { return (IEnumerable)GetValue(DataGridItemSourceProperty); }
set { SetValue(DataGridItemSourceProperty, value); }
}
我有一个 window,我需要使用不同的 ItemsSources 绑定此 UserControl 2 次。但是两个来源在第一个 属性 之前都具有相同的属性。来源是:
GroupNumber:
Number, int
Text, string
Comment, string
GroupUnit:
Unt, int
Text, string
Comment, string
两者的行为相同。有没有办法根据 ItemsSource 设置 1 DataGrid 列的绑定?
我试过这样的事情:
void GroupPanel_Loaded(object sender, RoutedEventArgs e)
{
var type = DataGridItemSource.GetType();
if(type.FullName.Contains("GroupNumber"))
{
}
}
但我不知道如何在 if...
中设置列绑定
提前致谢
您可以将另一个依赖项 属性 添加到您的 GroupPanel
用户控件:
public string FirstColumnBindingPropertyName
{
get { return (string)GetValue(FirstColumnBindingPropertyNameProperty); }
set { SetValue(FirstColumnBindingPropertyNameProperty, value); }
}
public static readonly DependencyProperty FirstColumnBindingPropertyNameProperty =
DependencyProperty.Register("FirstColumnBindingPropertyName", typeof(string), typeof(GroupPanel), new UIPropertyMetadata(null, new PropertyChangedCallback(OnFirstColumnBindingPropertyNameChanged)));
private static void OnFirstColumnBindingPropertyNameChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
GroupPanel groupPanel = (GroupPanel)dependencyObject;
DataGridTextColumn dataGridTextColumn = groupPanel.mainGrid.Columns[0] as DataGridTextColumn;
if (args.NewValue == null)
{
dataGridTextColumn.Binding = null;
}
else
{
dataGridTextColumn.Binding = new Binding(Convert.ToString(args.NewValue));
}
}
那么在你的 window 中你将拥有:
<local:GroupPanel FirstColumnBindingPropertyName="Number" />
<local:GroupPanel FirstColumnBindingPropertyName="Unt" />
您可以使用 DataTemplateSelector。请参考以下代码。
<Window x:Class="DataTemplateSelector_Learning.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataTemplateSelector_Learning"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="GroupNumber">
<TextBlock Text="{Binding Number}"/>
</DataTemplate>
<DataTemplate x:Key="GroupUnit">
<TextBlock Text="{Binding Unit}" />
</DataTemplate>
</Window.Resources>
<StackPanel>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
Name="numGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="GroupNumber">
<DataGridTemplateColumn.CellTemplateSelector>
<local:GroupTemplateSelector
GroupNumber="{StaticResource GroupNumber}"
GroupUnit="{StaticResource GroupUnit}"/>
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
Name="unitGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="GroupUnit">
<DataGridTemplateColumn.CellTemplateSelector>
<local:GroupTemplateSelector
GroupNumber="{StaticResource GroupNumber}"
GroupUnit="{StaticResource GroupUnit}"/>
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ObservableCollection<GroupNumber> lstNum = new ObservableCollection<GroupNumber>();
lstNum.Add(new GroupNumber() { Number=1,Text="Test",Comment="Comment"});
numGrid.ItemsSource = lstNum;
ObservableCollection<Groupunit> lstUnit = new ObservableCollection<Groupunit>();
lstUnit.Add(new Groupunit() { Unit = 2, Text = "Test", Comment = "Comment" });
unitGrid.ItemsSource = lstUnit;
}
}
public class GroupTemplateSelector : DataTemplateSelector
{
public DataTemplate GroupNumber
{ get; set; }
public DataTemplate GroupUnit
{ get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is GroupNumber)
{
return GroupNumber;
}
else if (item is Groupunit)
{
return GroupUnit;
}
else
return base.SelectTemplate(item, container);
}
}
public class GroupNumber
{
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
private string comment;
public string Comment
{
get { return comment; }
set { comment = value; }
}
}
public class Groupunit
{
private int unit;
public int Unit
{
get { return unit; }
set { unit = value; }
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
private string comment;
public string Comment
{
get { return comment; }
set { comment = value; }
}
}
我已经在我的程序中创建了一个 UserControl 以实现可重用性:
GroupPanel.xaml:
<UserControl x:Class="View.UserControls.GroupPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"assembly=ViewModel"
Name="root">
<DockPanel>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="True"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
DataContext="{Binding ElementName=root}"
ItemsSource="{Binding DataGridItemSource}"
Name="mainGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Nr/Unit"
Binding="{Binding Nr}" />
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
和一个依赖项 属性 来设置 DataGrid 的 ItemsSource:
GroupPanel.xaml.cs:
public static readonly DependencyProperty DataGridItemSourceProperty =
DependencyProperty.Register("DataGridItemSource", typeof(IEnumerable), typeof(GroupPanel),
new PropertyMetadata(null));
public IEnumerable DataGridItemSource
{
get { return (IEnumerable)GetValue(DataGridItemSourceProperty); }
set { SetValue(DataGridItemSourceProperty, value); }
}
我有一个 window,我需要使用不同的 ItemsSources 绑定此 UserControl 2 次。但是两个来源在第一个 属性 之前都具有相同的属性。来源是:
GroupNumber:
Number, int
Text, string
Comment, string
GroupUnit:
Unt, int
Text, string
Comment, string
两者的行为相同。有没有办法根据 ItemsSource 设置 1 DataGrid 列的绑定?
我试过这样的事情:
void GroupPanel_Loaded(object sender, RoutedEventArgs e)
{
var type = DataGridItemSource.GetType();
if(type.FullName.Contains("GroupNumber"))
{
}
}
但我不知道如何在 if...
中设置列绑定提前致谢
您可以将另一个依赖项 属性 添加到您的 GroupPanel
用户控件:
public string FirstColumnBindingPropertyName
{
get { return (string)GetValue(FirstColumnBindingPropertyNameProperty); }
set { SetValue(FirstColumnBindingPropertyNameProperty, value); }
}
public static readonly DependencyProperty FirstColumnBindingPropertyNameProperty =
DependencyProperty.Register("FirstColumnBindingPropertyName", typeof(string), typeof(GroupPanel), new UIPropertyMetadata(null, new PropertyChangedCallback(OnFirstColumnBindingPropertyNameChanged)));
private static void OnFirstColumnBindingPropertyNameChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
GroupPanel groupPanel = (GroupPanel)dependencyObject;
DataGridTextColumn dataGridTextColumn = groupPanel.mainGrid.Columns[0] as DataGridTextColumn;
if (args.NewValue == null)
{
dataGridTextColumn.Binding = null;
}
else
{
dataGridTextColumn.Binding = new Binding(Convert.ToString(args.NewValue));
}
}
那么在你的 window 中你将拥有:
<local:GroupPanel FirstColumnBindingPropertyName="Number" />
<local:GroupPanel FirstColumnBindingPropertyName="Unt" />
您可以使用 DataTemplateSelector。请参考以下代码。
<Window x:Class="DataTemplateSelector_Learning.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataTemplateSelector_Learning"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="GroupNumber">
<TextBlock Text="{Binding Number}"/>
</DataTemplate>
<DataTemplate x:Key="GroupUnit">
<TextBlock Text="{Binding Unit}" />
</DataTemplate>
</Window.Resources>
<StackPanel>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
Name="numGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="GroupNumber">
<DataGridTemplateColumn.CellTemplateSelector>
<local:GroupTemplateSelector
GroupNumber="{StaticResource GroupNumber}"
GroupUnit="{StaticResource GroupUnit}"/>
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<DataGrid DockPanel.Dock="Top"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
Name="unitGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="GroupUnit">
<DataGridTemplateColumn.CellTemplateSelector>
<local:GroupTemplateSelector
GroupNumber="{StaticResource GroupNumber}"
GroupUnit="{StaticResource GroupUnit}"/>
</DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Text"
Binding="{Binding Text}" />
<DataGridTextColumn Header="Comment"
Binding="{Binding Comment}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Content="Delete" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ObservableCollection<GroupNumber> lstNum = new ObservableCollection<GroupNumber>();
lstNum.Add(new GroupNumber() { Number=1,Text="Test",Comment="Comment"});
numGrid.ItemsSource = lstNum;
ObservableCollection<Groupunit> lstUnit = new ObservableCollection<Groupunit>();
lstUnit.Add(new Groupunit() { Unit = 2, Text = "Test", Comment = "Comment" });
unitGrid.ItemsSource = lstUnit;
}
}
public class GroupTemplateSelector : DataTemplateSelector
{
public DataTemplate GroupNumber
{ get; set; }
public DataTemplate GroupUnit
{ get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is GroupNumber)
{
return GroupNumber;
}
else if (item is Groupunit)
{
return GroupUnit;
}
else
return base.SelectTemplate(item, container);
}
}
public class GroupNumber
{
private int number;
public int Number
{
get { return number; }
set { number = value; }
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
private string comment;
public string Comment
{
get { return comment; }
set { comment = value; }
}
}
public class Groupunit
{
private int unit;
public int Unit
{
get { return unit; }
set { unit = value; }
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
private string comment;
public string Comment
{
get { return comment; }
set { comment = value; }
}
}