如何将XAML中的控件设置为公开,以便在其他类中可见?

36

我正在工作中的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值?


1
请参见 http://stackoverflow.com/questions/10392348/how-to-make-a-label-static ,但您需要使用复选框。 - Liam McInroy
2个回答

79

你可以使用以下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>
现在你可以将你的复选框绑定到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函数,那么该怎么做呢? - Tak
@user1460166 无论如何,您的第二个项目(带有类x)需要引用第一个项目(带有XAML)。然后您有两个选项:(1)您可以在XAML中将CheckBox作为公共字段。然后,您需要在类x中引用此类的实例,以便在方法y中读取它。(2)更清晰的方法是使用一个单独的类和一个布尔属性。您将此类的实例设置为XAML中的DataContext,并将属性绑定到CheckBox IsChecked属性。在类x中,您引用相同类的实例并在方法y中读取属性。 - Damir Arh
@user1460166 你可以将任何类设置为DataContext。我已经更新了答案并提供了额外的信息。为了避免循环依赖,你需要在被XAML项目引用的class x所在的项目中定义两个项目都需要的类,或者创建一个新的库项目,被两个项目引用,并在其中定义该类。 - Damir Arh
@user1460166 我注意到你在此期间发布了一个新问题,这很有道理,因为它与此问题没有直接关系。如果这里的任何答案帮助你解决了问题,你可能想要接受其中一个答案。 - Damir Arh
(1)如果您不使用XAML,则将其添加到xaml.cs文件的构造函数中,在InitializeComponent()行的下方。 (2)这取决于您的代码外观。其中一个选项是在创建实例时使用OnRender函数将其设置为类的属性。 - Damir Arh
显示剩余11条评论

8
不要将复选框显示给外部,只需将当前状态传递给函数或类。还应考虑将复选框的值绑定DataContext中的类,大多数情况下可以避免直接访问控件在WPF中,也可以参见MVVM模式

问题是我想在onrender函数中使用复选框的值,您能否给出一个代码示例告诉我如何做到这一点? - Tak
@user1460166:我无法给你一个代码示例,因为我不知道你的确切对象关系。但你仍然可以将IsChecked绑定到一个在OnRender中可访问的对象实例上。方法名称听起来像是你有一个控件,那么该控件可能具有一个Parameters属性,其中包含一个布尔值,你可以将其绑定到CheckBox.IsChecked - H.B.
你能帮我看一下我的另一个问题吗?我在这里添加了我的代码示例:http://stackoverflow.com/questions/11462782/access-the-value-of-button-and-checkbox-of-an-xaml-in-other-another-class-in-a-w - Tak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接