Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF将控件绑定到另一个控件_C#_Wpf_Xaml_Datagrid_Combobox - Fatal编程技术网

C# 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

我有以下WPF窗口。更改#电缆的值会将选项卡添加(或删除)到
TabControl
(C2、C3、C4…)。更改#阶段会将新行添加到
数据网格

所有的选项卡(除了这个选项一)都有相同的格式,所以我创建了一个
UserControl-NTab
类,它有自己的.xaml和代码隐藏

现在,其他每个选项卡都有一个组合框,用户可以在其中选择适当的阶段(通过name属性)。要实现这一点,NTab需要了解选项选项卡中的阶段
DatGrid
。我的代码目前分为两类:

  • main窗口
    ,其中包含整个窗口和选项选项卡的代码(.xaml和代码隐藏)
  • NTab
    ,它包含自身的代码(.xaml和代码隐藏)
Phase
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&lt;NPhase&gt;</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&lt;NPhase&gt;</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,这正是我不知道如何做的