C# 如何访问WPF用户控件';视图模型中的s元素是选项卡项的内容?

C# 如何访问WPF用户控件';视图模型中的s元素是选项卡项的内容?,c#,wpf,mvvm,C#,Wpf,Mvvm,在WPF应用程序中,我有一个由四个文本框组成的用户控件。六个这样的用户控件组成一个数据模板,我使用它在主窗口中填充TabControl的选项卡项。数据模板的内容通过viewmodel绑定到数据层。 我的问题是,我找不到从视图(主窗口)访问每个单独文本框的IsEnabled属性的方法。使用VisualTreeHelper无助于精确定位文本框,因为作为每个选项卡项内容的viewmodel不是可视的。所以我最多只能得到一个TextBox实例的引用,但它可以同时在所有选项卡上工作。 谁能帮我做这个吗 编

在WPF应用程序中,我有一个由四个文本框组成的用户控件。六个这样的用户控件组成一个数据模板,我使用它在主窗口中填充TabControl的选项卡项。数据模板的内容通过viewmodel绑定到数据层。 我的问题是,我找不到从视图(主窗口)访问每个单独文本框的IsEnabled属性的方法。使用VisualTreeHelper无助于精确定位文本框,因为作为每个选项卡项内容的viewmodel不是可视的。所以我最多只能得到一个TextBox实例的引用,但它可以同时在所有选项卡上工作。 谁能帮我做这个吗

编辑: 下面是简化的代码片段,以便更好地理解我的问题

UserControl XAML:

UserControl x:Class="WpfApplication4.MyModuleFrame"
     <!-- ... -->
     x:Name="mUserControl">
  <Grid>
     <!-- ... -->
    <TextBox Text="{Binding ItemSource.Ch1, ElementName=mUserControl}" Name="txtCh1"/>
    <!-- other textboxes -->
  </Grid>
</UserControl>
模块C:

namespace WpfApplication4
{
  public class Module: INotifyPropertyChanged
  {

    private double _ch1;
    public double Ch1
    {
        get { return this._ch1; }
        set
        {
            if (_ch1 == value) return;
            _ch1 = value;
            OnPropertyChanged("Ch1");
        }
    }
    ...
    ...
    ...
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string aNameOfProperty)
    {
        if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(aNameOfProperty));
    }
ViewModel.cs:

namespace WpfApplication4
{
public class MainViewModel: INotifyPropertyChanged
{
    public Module Module1 { get; set; }
    public Module Module2 { get; set; }
    public Module Module3 { get; set; }
    public Module Module4 { get; set; }
    public Module Module5 { get; set; }
    public Module Module6 { get; set; }

    public MainViewModel()
    {
        Module1 = new Module() { Number = "1", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
        Module2 = new Module() { Number = "2", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
        Module3 = new Module() { Number = "3", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
        Module4 = new Module() { Number = "4", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
        Module5 = new Module() { Number = "5", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
        Module6 = new Module() { Number = "6", Ch1 = 123.4, Ch2 = 123.4, Ch3 = 123.4, Ch4 = 123.4 };
    }
...        
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void RaisePropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
主窗口XAML:

<Window x:Class="WpfApplication4.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    <!-- ... -->
    Title="Window1" Height="800" Width="1000" x:Name="wndMain"
    DataContext = "{StaticResource MainViewModel}">
<Window.Resources>
    <DataTemplate x:Key="tabTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="210" />
                <RowDefinition Height="30" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <loc:MyModuleFrame Name="mmf1" Grid.Row="1" Grid.Column="0" ItemSource="{Binding Module1}"/>
            <loc:MyModuleFrame Name="mmf2" Grid.Row="1" Grid.Column="1" ItemSource="{Binding Module2}"/>
            <loc:MyModuleFrame Name="mmf3" Grid.Row="1" Grid.Column="2" ItemSource="{Binding Module3}"/>
            <loc:MyModuleFrame Name="mmf4" Grid.Row="1" Grid.Column="3" ItemSource="{Binding Module4}"/>
            <loc:MyModuleFrame Name="mmf5" Grid.Row="1" Grid.Column="4" ItemSource="{Binding Module5}"/>
            <loc:MyModuleFrame Name="mmf6" Grid.Row="1" Grid.Column="5" ItemSource="{Binding Module6}"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
  <Grid>
    <TabControl Grid.Row="0" Name="tabHolder" SelectedIndex="{Binding Selected}" HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch" Height="Auto" Width="Auto" 
                ContentTemplate="{StaticResource tabTemplate}">
    </TabControl>

  </Grid>
</Window>

请随时发布一些代码,以获得更好的信息和来自他人的有用帮助

我尽可能地解释,我希望这有助于:


你提到了ViewModel,所以我认为你使用的是MVVM,这是一个很好的方法。在这种方法中,您可以通过绑定访问UI元素,因此需要在每个级别中公开一个
dependencProperty

Hi!感谢您的反馈!我刚刚添加了代码@埃马德
<Window x:Class="WpfApplication4.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    <!-- ... -->
    Title="Window1" Height="800" Width="1000" x:Name="wndMain"
    DataContext = "{StaticResource MainViewModel}">
<Window.Resources>
    <DataTemplate x:Key="tabTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="210" />
                <RowDefinition Height="30" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <loc:MyModuleFrame Name="mmf1" Grid.Row="1" Grid.Column="0" ItemSource="{Binding Module1}"/>
            <loc:MyModuleFrame Name="mmf2" Grid.Row="1" Grid.Column="1" ItemSource="{Binding Module2}"/>
            <loc:MyModuleFrame Name="mmf3" Grid.Row="1" Grid.Column="2" ItemSource="{Binding Module3}"/>
            <loc:MyModuleFrame Name="mmf4" Grid.Row="1" Grid.Column="3" ItemSource="{Binding Module4}"/>
            <loc:MyModuleFrame Name="mmf5" Grid.Row="1" Grid.Column="4" ItemSource="{Binding Module5}"/>
            <loc:MyModuleFrame Name="mmf6" Grid.Row="1" Grid.Column="5" ItemSource="{Binding Module6}"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
  <Grid>
    <TabControl Grid.Row="0" Name="tabHolder" SelectedIndex="{Binding Selected}" HorizontalAlignment="Stretch" Margin="10" VerticalAlignment="Stretch" Height="Auto" Width="Auto" 
                ContentTemplate="{StaticResource tabTemplate}">
    </TabControl>

  </Grid>
</Window>
namespace WpfApplication4
{
  public partial class Window1 : Window
  {

    protected List<MainViewModel> viewmodels;

    public Window1()
    {
        InitializeComponent();

        viewmodels = new List<MainViewModel>();
        viewmodels.Add(new MainViewModel());
        viewmodels.Add(new MainViewModel());
        viewmodels.Add(new MainViewModel());

        tabHolder.ItemsSource = viewmodels;
    }
  }
}