C# 如何在 XAML 中公开控件以便在其他类中可见

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11425153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 17:50:00  来源:igfitidea点击:

How to make a control in XAML public in order to be seen in other classes

c#wpfxamlcheckboxkinect

提问by Tak

I'm working in wpf application i made a checkbox in the XAML, then my code calls a function in a class and in this function there is an if condition where its checking on whether the checkbox is checked or not but the checkbox is not seen in this class, so how to do this?

我在 wpf 应用程序中工作,我在 XAML 中创建了一个复选框,然后我的代码调用了一个类中的函数,在这个函数中有一个 if 条件,它检查是否选中了复选框但未看到复选框在这个类中,那么如何做到这一点?

Many thanks

非常感谢

EDIT:

编辑:

Here is the steps I did: i created the ViewModel class under the same project of KinectSkeleton as shown: ViewModel class:

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

public class ViewModel
{
    public bool IsChecked { get; set; }
    public bool is_clicked { get; set; }
}

and in the KinectSkeleton I defined a property as shown:

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

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


public ViewModel ViewModelH
{
    get
    {
        return (ViewModel)GetValue(ViewModelProperty);
    }
    set
    {
        SetValue(ViewModelProperty, value);
    }
}

and the code of the checkbox and button in the KinectWindow.xaml is :

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" />

and in the KinectSkeleton where i want to check the value of the checkbox i write:

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

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

now i want to know what to write in the is_checked event of the checkbox and is_clicked of the button? also is there anything missing in my above steps as i feel that till now the kinect skeleton property is not binded to the checkbox is_checked value?

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

采纳答案by Damir Arh

Using the following XML you can define a control as a public field on the class to be able to access it from other classes:

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

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

Now you can access the field directly in code:

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

if (win.myCheckBox.IsChecked.Value)
{
    // ...
}

I agree with H.B., though, that using the MVVM pattern is a better way to do it. Other parts of your code shouldn't be aware of your UI or directly access it.

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

EDIT:

编辑:

With the MVVM approach you should first define your view model class:

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

public class ViewModel
{
    public bool IsChecked { get; set; }
}

Then you set an instance of this class as DataContext:

然后将此类的实例设置为DataContext

  • either in code, e.g. window constructor:
  • 无论是在代码中,例如窗口构造函数:
public MyWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}
public MyWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}
  • or in XAML, e.g. App.xaml:
  • 或在 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>
<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>

Now you can bind your CheckBox to a property in ViewModel:

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

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

All that's left is to pass the ViewModelinstance to your OnRenderfunction. It is stored in the DataContextproperty of your window.

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

EDIT 2:

编辑2:

BTW: You really should have asked that before you accepted the answer.

BTW:你真的应该在接受答案之前问这个问题。

I'm not sure what you are trying to attempt with the is_clickedproperty. To set this flag when the button is clicked, you need a Command:

我不确定您要尝试使用该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;
    }
}

You add an instance of this command to your view model:

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

public class ViewModel
{
    public bool IsChecked { get; set; }
    public bool IsClicked { get; set; }
    public ICommand CalibrateCommand { get; set; }

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

You bind it to the button like 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}" />

You don't need to handle any events of the CheckBoxand the Button, everything is handled by the binding.

您不需要处理CheckBox和 的任何事件Button,一切都由绑定处理。

If you added a dependency property to KinectSkeletonyou should bind it to the view model:

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

<kt:KinectSkeleton ViewModelH="{Binding}" />

回答by H.B.

Don't make the checkbox visible to the outside, just pass the current state of the checkbox to the function or class. Also consider bindingthe checkbox value to a class in the DataContext, directly accessing controls can be avoided most of the time in WPF, see also the MVVM pattern.

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