C# WPF将控件绑定到另一个控件
我有以下WPF窗口。更改#电缆的值会将选项卡添加(或删除)到C# WPF将控件绑定到另一个控件,c#,wpf,xaml,datagrid,combobox,C#,Wpf,Xaml,Datagrid,Combobox,我有以下WPF窗口。更改#电缆的值会将选项卡添加(或删除)到TabControl(C2、C3、C4…)。更改#阶段会将新行添加到数据网格 所有的选项卡(除了这个选项一)都有相同的格式,所以我创建了一个UserControl-NTab类,它有自己的.xaml和代码隐藏 现在,其他每个选项卡都有一个组合框,用户可以在其中选择适当的阶段(通过name属性)。要实现这一点,NTab需要了解选项选项卡中的阶段DatGrid。我的代码目前分为两类: main窗口,其中包含整个窗口和选项选项卡的代码(.x
TabControl
(C2、C3、C4…)。更改#阶段会将新行添加到数据网格
所有的选项卡(除了这个选项一)都有相同的格式,所以我创建了一个UserControl-NTab
类,它有自己的.xaml和代码隐藏
现在,其他每个选项卡都有一个组合框,用户可以在其中选择适当的阶段(通过name属性)。要实现这一点,NTab需要了解选项选项卡中的阶段DatGrid
。我的代码目前分为两类:
,其中包含整个窗口和选项选项卡的代码(.xaml和代码隐藏)李>main窗口
,它包含自身的代码(.xaml和代码隐藏)NTab
DataGrid的ItemSource
是一个ObservableCollection
,因此我所做的是将集合发送给NTab
构造函数,并将其.CollectionChanged
事件绑定到以下NTab
函数(Phase是一个ObservableCollection
依赖属性):
MainWindow.xaml.cs
public partial class MainWindow : Window
{
ObservableCollection<NPhase> Phases;
public static DependencyProperty PhasesProperty = DependencyProperty.Register("Phases", typeof(ICollectionView), typeof(MainWindow));
public ICollectionView IPhasesCollection
{
get { return (ICollectionView)GetValue(PhasesProperty); }
set { SetValue(PhasesProperty, value); }
}
/// <summary>Controls the number of cables to be created</summary>
/// <param name="sender">(IntegerUpDown)nCables</param>
/// <param name="e">not used</param>
private void nCablesChanged(object sender, RoutedEventArgs e)
{
int n = tabControl.Items.Count - 1;
var o = sender as IntegerUpDown;
int v = (int)o.Value;
if (v > n)
{
for (int i = n; i < v; i++)
{
TabItem tab = new TabItem();
tab.Header = "C" + (i + 1);
tab.Content = new NTab(Phases);
tabControl.Items.Add(tab);
}
}
else if (v < n)
{
for (int i = v; i < n; i++)
tabControl.Items.RemoveAt(n);
}
}
/// <summary>Modifies the DataGrid according to the number of phases desired</summary>
/// <param name="sender">(IntegerUpDown)nPhases</param>
/// <param name="e">not used</param>
private void nPhasesChanged(object sender, RoutedEventArgs e)
{
//...
}
/// <summary>Sets up the row headers</summary>
/// <param name="sender">not used</param>
/// <param name="e">Row to be modified</param>
private void RowIndex(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex() + 1).ToString();
}
public MainWindow()
{
Phases = new ObservableCollection<NPhase>();
Phases.Add(new NPhase(3, "Protensao Inicial"));
Phases.Add(new NPhase(28, "Carga Movel"));
Phases.Add(new NPhase(365, "1 Ano"));
Phases.Add(new NPhase(18250, "Vida Util"));
IPhasesCollection = CollectionViewSource.GetDefaultView(Phases);
InitializeComponent();
}
}
public partial class NTab : UserControl
{
ObservableCollection<string> Phases;
public static DependencyProperty PhasesProperty = DependencyProperty.Register("Phases", typeof(ICollectionView), typeof(NTab));
public ICollectionView IPhasesCollection
{
get { return (ICollectionView)GetValue(PhasesProperty); }
set { SetValue(PhasesProperty, value); }
}
/// <summary>Updates the tab's Phase list to match the list in the Options tab.</summary>
/// <param name="source">(ObservableCollection<NPhase></param>
/// <param name="e">not used.</param>
public void PhasesChanged(object source, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var pC = source as ObservableCollection<NPhase>;
Phases.Clear();
for (int i = 0; i < pC.Count; i++)
Phases.Add("" + (i + 1));
}
public NTab(ObservableCollection<NPhase> p)
{
InitializeComponent();
Phases = new ObservableCollection<string>();
IPhasesCollection = CollectionViewSource.GetDefaultView(Phases);
PhasesChanged(p, new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
p.CollectionChanged += PhasesChanged;
}
}
公共部分类主窗口:窗口
{
可观察到的收集阶段;
public static dependencProperty phaseProperty=dependencProperty.Register(“阶段”、typeof(ICollectionView)、typeof(主窗口));
公共ICollectionView IPhasesCollection
{
get{return(ICollectionView)GetValue(PhasesProperty);}
set{SetValue(相位属性,值);}
}
///控制要创建的电缆数
///(整数向下)nCables
///不用
私有void nCablesChanged(对象发送方,路由目标)
{
int n=tabControl.Items.Count-1;
var o=发送方作为整数下降;
int v=(int)o.值;
如果(v>n)
{
对于(int i=n;i
NTab.xaml
<Window x:Class="WPF.MainWindow"
x:Name="Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:l="clr-namespace:WPF"
Title="WPF" SizeToContent="WidthAndHeight">
<TabControl Name="tabControl" SelectedIndex="1">
<TabItem Name="Options">
<TabItem.Header>
<TextBlock>Options</TextBlock>
</TabItem.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- ... -->
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<!-- ... -->
</Grid.ColumnDefinitions>
<Label Grid.Column="0"># Cables</Label>
<xctk:IntegerUpDown Name="nCables"
Grid.Column="1"
Minimum="1"
Value="1"
ValueChanged="nCablesChanged"/>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<!-- ... -->
</Grid.ColumnDefinitions>
<Label Grid.Column="0"># Phases</Label>
<xctk:IntegerUpDown Name="nPhases"
Grid.Column="1"
Minimum="1"
Value="4"
ValueChanged="nPhasesChanged"/>
</Grid>
<l:NDataGrid Grid.Row="2"
x:Name="PhaseGrid"
ItemsSource="{Binding Phases, ElementName=Main}"
LoadingRow="RowIndex"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserSortColumns="False"
VerticalScrollBarVisibility="Hidden"
Block.TextAlignment="Center"/>
</Grid>
</TabItem>
</TabControl>
</Window>
<UserControl x:Class="WPF.NTab"
x:Name="CableTab"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:charting="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:l="clr-namespace:WPF"
mc:Ignorable="d" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- ... -->
</Grid.RowDefinitions>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<!-- ... -->
</Grid.ColumnDefinitions>
<Label Grid.Column="2">Pull Phase</Label>
<ComboBox Grid.Column="3"
Name="Phase"
ItemsSource="{Binding Phases, ElementName=CableTab}"/>
</Grid>
</Grid>
</UserControl>
牵引阶段
NTab.xaml.cs
public partial class MainWindow : Window
{
ObservableCollection<NPhase> Phases;
public static DependencyProperty PhasesProperty = DependencyProperty.Register("Phases", typeof(ICollectionView), typeof(MainWindow));
public ICollectionView IPhasesCollection
{
get { return (ICollectionView)GetValue(PhasesProperty); }
set { SetValue(PhasesProperty, value); }
}
/// <summary>Controls the number of cables to be created</summary>
/// <param name="sender">(IntegerUpDown)nCables</param>
/// <param name="e">not used</param>
private void nCablesChanged(object sender, RoutedEventArgs e)
{
int n = tabControl.Items.Count - 1;
var o = sender as IntegerUpDown;
int v = (int)o.Value;
if (v > n)
{
for (int i = n; i < v; i++)
{
TabItem tab = new TabItem();
tab.Header = "C" + (i + 1);
tab.Content = new NTab(Phases);
tabControl.Items.Add(tab);
}
}
else if (v < n)
{
for (int i = v; i < n; i++)
tabControl.Items.RemoveAt(n);
}
}
/// <summary>Modifies the DataGrid according to the number of phases desired</summary>
/// <param name="sender">(IntegerUpDown)nPhases</param>
/// <param name="e">not used</param>
private void nPhasesChanged(object sender, RoutedEventArgs e)
{
//...
}
/// <summary>Sets up the row headers</summary>
/// <param name="sender">not used</param>
/// <param name="e">Row to be modified</param>
private void RowIndex(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex() + 1).ToString();
}
public MainWindow()
{
Phases = new ObservableCollection<NPhase>();
Phases.Add(new NPhase(3, "Protensao Inicial"));
Phases.Add(new NPhase(28, "Carga Movel"));
Phases.Add(new NPhase(365, "1 Ano"));
Phases.Add(new NPhase(18250, "Vida Util"));
IPhasesCollection = CollectionViewSource.GetDefaultView(Phases);
InitializeComponent();
}
}
public partial class NTab : UserControl
{
ObservableCollection<string> Phases;
public static DependencyProperty PhasesProperty = DependencyProperty.Register("Phases", typeof(ICollectionView), typeof(NTab));
public ICollectionView IPhasesCollection
{
get { return (ICollectionView)GetValue(PhasesProperty); }
set { SetValue(PhasesProperty, value); }
}
/// <summary>Updates the tab's Phase list to match the list in the Options tab.</summary>
/// <param name="source">(ObservableCollection<NPhase></param>
/// <param name="e">not used.</param>
public void PhasesChanged(object source, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var pC = source as ObservableCollection<NPhase>;
Phases.Clear();
for (int i = 0; i < pC.Count; i++)
Phases.Add("" + (i + 1));
}
public NTab(ObservableCollection<NPhase> p)
{
InitializeComponent();
Phases = new ObservableCollection<string>();
IPhasesCollection = CollectionViewSource.GetDefaultView(Phases);
PhasesChanged(p, new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
p.CollectionChanged += PhasesChanged;
}
}
公共部分类NTab:UserControl
{
可观察到的收集阶段;
public static dependencProperty phaseProperty=dependencProperty.Register(“阶段”、typeof(ICollectionView)、typeof(NTab));
公共ICollectionView IPhasesCollection
{
get{return(ICollectionView)GetValue(PhasesProperty);}
set{SetValue(相位属性,值);}
}
///更新选项卡的阶段列表以匹配“选项”选项卡中的列表。
///(可观察到的收集阶段)
///没有用。
公共无效阶段已更改(对象源,System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var pC=作为可观测集合的来源;
阶段。清除();
对于(int i=0;i
您的看法是错误的……在WPF中,当一个UI控件需要了解另一个UI控件的任何信息时,这是一种罕见的情况。处理数据更常见。我的意思是,您的NTab
只需要知道来自阶段数据网格的数据,而不需要知道控件
实现这一点的最简单方法是为整个TabControl
使用一个视图模型,该模型在各个TabItem
上共享其属性。因此,与其试图处理UI事件以保持集合不变,不如对所有TabItem
使用一个集合。在数据网格中,您可以这样做这:
<DataGrid ItemsSource="{Binding YourCollection}" ... />
这样,一个TabItem
中集合的更新将自动反映在所有其他TabItem
中,而无需您做任何事情。您可以向我们展示您的XAML吗please@lll问题是,除了这一条信息(阶段),每个选项卡完全独立于其他选项卡。此外,如果有任何用处,我已经用我的代码更新了OP。我不清楚“只对所有选项卡项使用一个集合”是什么意思。你是指所有选项卡的一个阶段集合吗?因为考虑到NTa,这正是我不知道如何做的