如何在 XAML 中公开控件以便在其他类中看到

Posted

技术标签:

【中文标题】如何在 XAML 中公开控件以便在其他类中看到【英文标题】:How to make a control in XAML public in order to be seen in other classes 【发布时间】:2012-07-10 15:04:48 【问题描述】:

我在 wpf 应用程序中工作我在 XAML 中创建了一个复选框,然后我的代码调用了一个类中的一个函数,并且在这个函数中有一个 if 条件,它检查复选框是否被选中,但复选框在这个类中没有看到,那怎么办呢?

非常感谢

编辑:

以下是我执行的步骤: 我在 KinectSkeleton 的同一个项目下创建了 ViewModel 类,如图所示: ViewModel 类:

public class ViewModel

    public bool IsChecked  get; set; 
    public bool is_clicked  get; set; 

我在 KinectSkeleton 中定义了一个属性,如下所示:

public static readonly DependencyProperty ViewModelProperty =
           DependencyProperty.Register("ViewModelH", typeof(ViewModel), typeof(KinectSkeleton), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
  

public ViewModel ViewModelH

    get => (ViewModel)GetValue(ViewModelProperty);
    set => SetValue(ViewModelProperty, value);

KinectWindow.xaml中复选框和按钮的代码是:

<Button Content="Calibrate" Height="24" x:Name="Calibrate" x:FieldModifier="public" Width="90" Click="Calibrate_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" DockPanel.Dock="Left" Panel.ZIndex="0" Padding="0" VerticalAlignment="Center" />
<CheckBox IsChecked="Binding Mode=TwoWay, Path=IsChecked" Content="AngleDifference" Height="22" x:Name="AngleDifference" x:FieldModifier="public" Width="117" Checked="AngleDifference_Checked" Unchecked="AngleDifference_Unchecked" HorizontalAlignment="Left" VerticalAlignment="Center" Panel.ZIndex="1" HorizontalContentAlignment="Left" />

在我想检查我写的复选框的值的 KinectSkeleton 中:

    if (this.ViewModelH.IsChecked == false)
    // if(f.is_chekced == false)
    
        // do something
    

现在我想知道在复选框的 is_checked 事件和按钮的 is_clicked 事件中写什么?另外,我的上述步骤中是否缺少任何内容,因为我觉得到目前为止 Kinect 骨架属性未绑定到复选框 is_checked 值?

【问题讨论】:

见***.com/questions/10392348/how-to-make-a-label-static只有你会使用复选框 【参考方案1】:

使用以下 XML,您可以将控件定义为类上的公共字段,以便能够从其他类访问它:

<CheckBox x:Name="myCheckBox" x:FieldModifier="public" />

现在您可以直接在代码中访问该字段:

if (win.myCheckBox.IsChecked.Value)

    // ...

不过,我同意 H.B. 的观点,即使用 MVVM 模式是一种更好的方法。您的代码的其他部分不应该知道您的 UI 或直接访问它。

编辑:

使用 MVVM 方法,您应该首先定义您的视图模型类:

public class ViewModel

    public bool IsChecked  get; set; 

然后你将这个类的一个实例设置为DataContext:

在代码中,例如窗口构造函数:
public MyWindow()

    InitializeComponent();
    DataContext = new ViewModel();

或在 XAML 中,例如App.xaml:
<Application x:Class="WpfApplication2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:WpfApplication2"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <vm:ViewModel x:Key="ViewModel" />
    </Application.Resources>
</Application>

现在您可以将 CheckBox 绑定到 ViewModel 中的属性:

<CheckBox IsChecked="Binding IsChecked, Mode=TwoWay" />

剩下的就是将ViewModel 实例传递给您的OnRender 函数。它存储在窗口的DataContext 属性中。

编辑 2:

顺便说一句:你真的应该在接受答案之前问这个问题。

我不确定您要尝试使用 is_clicked 属性做什么。要在单击按钮时设置此标志,您需要 Command:

public class CalibrateCommand : ICommand

    private ViewModel viewModel;

    public CalibrateCommand(ViewModel viewModel)
    
        this.viewModel = viewModel;
    

    public void Execute(object parameter)
    
        viewModel.IsClicked = true;
    

    public bool CanExecute()
    
        return true;
    

您将此命令的一个实例添加到您的视图模型中:

public class ViewModel

    public bool IsChecked  get; set; 
    public bool IsClicked  get; set; 
    public ICommand CalibrateCommand  get; set; 

    public ViewModel()
    
        CalibrateCommand = new CalibrateCommand(this);
    

你可以像这样将它绑定到按钮上:

<Button Content="Calibrate" Height="24" x:Name="Calibrate" x:FieldModifier="public" Width="90" Click="Calibrate_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" DockPanel.Dock="Left" Panel.ZIndex="0" Padding="0" VerticalAlignment="Center" Command="Binding CalibrateCommand" />

你不需要处理CheckBoxButton的任何事件,一切都由绑定处理。

如果您向KinectSkeleton 添加了一个依赖属性,您应该将它绑定到视图模型:

<kt:KinectSkeleton ViewModelH="Binding" />

【讨论】:

好的,这是我的确切场景,我有一个项目包含和 xaml 文件及其 cs 文件,这个 xaml 有一个复选框,可以说 cb1,然后我有另一个项目有一个类 x 这个类有一个函数 y 必须使用复选框 cb1 的值,而这个函数是 onrender 函数,那么怎么做呢? @user1460166 在任何情况下,您的第二个项目(使用 x 类)都需要引用第一个项目(使用 XAML)。然后您有 2 个选项: (1) 您可以将 CheckBox 作为 XAML 中的公共字段。然后,您需要在类 x 中引用此类的实例,以便您可以在方法 y 中读取它。 (2) 更简洁的方法是使用具有布尔属性的单独类。您在 XAML 中将此类的一个实例设置为 DataContext 并将该属性绑定到 CheckBox IsChecked 属性。在类 x 中,您可以引用该类的同一实例并读取方法 y 中的属性。 问题是xaml已经引用了项目x,所以我不能在x中引用xaml,因为这会导致依赖循环,以及如何将类定义为XAML 中的数据上下文? @user1460166 您可以将任何类设置为 DataContext。我已经用其他信息更新了答案。为避免循环依赖,您需要使用 XAML 项目引用的类 x 定义项目中两个项目所需的类,或者创建两者都引用的新库项目并在那里定义类。 @user1460166 我注意到在此期间您将其发布为new question,这是有道理的,因为它与此没有直接关系。您可能想在这里接受它帮助您解决问题的答案之一。【参考方案2】:

不要让复选框对外可见,只需将复选框的当前状态传递给函数或类即可。还可以考虑binding将复选框值设置为DataContext中的一个类,在WPF中大部分时间可以避免直接访问控件,另见MVVM pattern。

【讨论】:

问题是我想在onrender函数中使用checkbox的值,你能通过代码示例告诉我怎么做吗? @user1460166:我不能给你一个代码示例,因为我不知道你的确切对象关系。您仍然应该能够将 IsChecked 绑定到可在 OnRender 中访问的对象实例。方法名称听起来像您有一个控件,然后该控件可以例如有一个Parameters 属性,其中包含一个带有一些布尔值的对象实例,您可以将其绑定到CheckBox.IsChecked 你能检查我的其他问题吗,我添加了我的代码示例:***.com/questions/11462782/…

以上是关于如何在 XAML 中公开控件以便在其他类中看到的主要内容,如果未能解决你的问题,请参考以下文章

如何让其他控件在自定义控件中看到 DataTables 的集合?

小白求教,WPF中如何让xaml控件在其他.cs文件中使用

如何公开公开控件的属性?

从其他 Xaml 文件绑定到用户控件中的元素

如何在 XAML 代码中创建支持其中其他元素的 UserControl

如何在我的 UIViewController 类中声明 UIImageView 以便其他类可以使用它?