Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.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#和#x2B;WPF:访问控件值时,我应该如何进行适当的检查/保护/强制转换?_C#_.net_Wpf_Casting - Fatal编程技术网

C#和#x2B;WPF:访问控件值时,我应该如何进行适当的检查/保护/强制转换?

C#和#x2B;WPF:访问控件值时,我应该如何进行适当的检查/保护/强制转换?,c#,.net,wpf,casting,C#,.net,Wpf,Casting,这可能是非常基本的,但在与其他语言合作多年后,我刚刚开始学习C语言,不幸的是,我已经习惯了松散和动态的键入。现在,在构建一个带有很多复选框的WPF表单时,我注意到,由于需要检查空值并强制转换结果,我的代码用于做一些简单的事情,比如确定是否选中复选框,实际上相当复杂。我最终得到的帮助函数如下: private bool isChecked(CheckBox control) { return control != null && control.IsChec

这可能是非常基本的,但在与其他语言合作多年后,我刚刚开始学习C语言,不幸的是,我已经习惯了松散和动态的键入。现在,在构建一个带有很多复选框的WPF表单时,我注意到,由于需要检查空值并强制转换结果,我的代码用于做一些简单的事情,比如确定是否选中复选框,实际上相当复杂。我最终得到的帮助函数如下:

    private bool isChecked(CheckBox control) {
        return control != null && control.IsChecked != null && control.IsChecked.HasValue && (bool)control.IsChecked;
    }
所以在我的逻辑代码中,我可以

    if (isChecked(opticsCheckBox))
    {
        // whatever I need to do if opticsCheckBox is checked
    }
这是用C#(使用WPF)做事情的正常方式,还是我遗漏了一些简单的东西?基本上,我发现嵌套的条件层总是检查每个对象是否为null,这是错误代码的警告标志(事实上,我可能会忘记检查)。但我不确定我应该做什么

我应该使用try。。。即使控件不存在或未检查也不是一种例外情况,也要到处捕获?在我看来,它最终也会变得杂乱无章

另一个澄清的例子是: 当我想写一些像:

    maxWeight = (int)maxWeightComboBox.SelectedItem;
我发现自己在写:

    if (maxWeightComboBox != null && maxWeightComboBox.SelectedItem != null)
    {
        ComboBoxItem item = (ComboBoxItem)maxWeightComboBox.SelectedItem;
        maxWeight = Int32.Parse(item.Content.ToString());
    }
一般来说,是的,C#比动态/丢失类型的语言更冗长。Java也是如此。看看你的具体例子

private bool isChecked(CheckBox control) {
    return control != null && control.IsChecked != null && control.IsChecked.HasValue && (bool)control.IsChecked;
}
有几点。。。以下两项检查是等效的:

control.IsChecked != null
control.IsChecked.HasValue
IsChecked属性是可为空的类型。由于您是C#新手,我建议您阅读价值类型与参考类型。一旦掌握了其中的诀窍,就可以了解如何使用可空类型包装值类型,以便为其分配空值。下面链接的页面解释了上述twp声明等效的原因:

control.IsChecked != null
control.IsChecked.HasValue

第二,你为什么要检查控制=无效的在典型的场景中,在窗口或UserControl上用XAML创建控件,通过x:Name属性进行标识。在这种情况下,您可以依赖UI中存在的控件并放弃此检查

您的另外两张支票是必需的;-)

把它们放在一个可以重复使用的方法中是个好主意。您还可以通过创建扩展方法来“扩展”语言,例如

private bool IsChecked(this CheckBox control) {
    return control.IsChecked.HasValue && (bool)control.IsChecked;
}

// calls the extension method above.
myCheckBox.IsChecked()
这很有帮助。

一般来说,是的,C#比动态/丢失类型的语言更冗长。Java也是如此。看看你的具体例子

private bool isChecked(CheckBox control) {
    return control != null && control.IsChecked != null && control.IsChecked.HasValue && (bool)control.IsChecked;
}
有几点。。。以下两项检查是等效的:

control.IsChecked != null
control.IsChecked.HasValue
IsChecked属性是可为空的类型。由于您是C#新手,我建议您阅读价值类型与参考类型。一旦掌握了其中的诀窍,就可以了解如何使用可空类型包装值类型,以便为其分配空值。下面链接的页面解释了上述twp声明等效的原因:

control.IsChecked != null
control.IsChecked.HasValue

第二,你为什么要检查控制=无效的在典型的场景中,在窗口或UserControl上用XAML创建控件,通过x:Name属性进行标识。在这种情况下,您可以依赖UI中存在的控件并放弃此检查

您的另外两张支票是必需的;-)

把它们放在一个可以重复使用的方法中是个好主意。您还可以通过创建扩展方法来“扩展”语言,例如

private bool IsChecked(this CheckBox control) {
    return control.IsChecked.HasValue && (bool)control.IsChecked;
}

// calls the extension method above.
myCheckBox.IsChecked()
这很有帮助。

不太详细的表单是

control != null && control.IsChecked == true
请记住,
bool?
有三个值,true、false和null,只需检查一个值即可。例如,
a==true
a!=false
分别是检查空值何时像false一样工作或空值何时像true一样工作

对于您的组合框示例,我首先使用强类型集合。有关如何直接绑定到整数的示例,请参见(或者如果需要单独的内容/值,请将其绑定到KeyValuePairs列表[例如]),然后使用SelectedValue和SelectedValuePath来减少值检索代码。

不太详细的表单是

control != null && control.IsChecked == true
请记住,
bool?
有三个值,true、false和null,只需检查一个值即可。例如,
a==true
a!=false
分别是检查空值何时像false一样工作或空值何时像true一样工作


对于您的组合框示例,我首先使用强类型集合。有关如何直接绑定到整数的示例,请参见(或者如果需要单独的内容/值,请将其绑定到KeyValuePairs列表[例如]),然后使用SelectedValue和SelectedValuePath减少值检索代码。

使用可空类型(包括引用),您可以使用
运算符指定对象为空时要使用的默认值。所以
control.IsChecked!=null&&control.IsChecked
可以替换为
control.IsChecked??错误
。这并不能解决所有问题,但在某些情况下,它有助于减少您键入的代码量。

对于可为空的类型(包括引用),您可以使用
运算符指定对象为空时要使用的默认值。所以
control.IsChecked!=null&&control.IsChecked
可以替换为
control.IsChecked??错误
。这并不能解决所有问题,但在某些情况下,它有助于减少键入的代码量。

WPF提供了属性更改通知、依赖属性和绑定等功能。 因此,WPF中的良好实践是使用PresentationModelView模式或MVC模式,而不是直接访问控件

您的表示模型(或控制器)必须处理所有业务逻辑,视图只反映模型的实际状态

在您的案例中,模型如下所示:

public class SampleModel : ObservableObject
{
    private bool? _isFirstChecked;
    public bool? IsFirstChecked
    {
        get
        {
            return this._isFirstChecked;
        }
        set
        {
            if (this._isFirstChecked != value)
            {
                this._isFirstChecked = value;
                this.OnPropertyChanged("IsFirstChecked");
            }
        }
    }

    private int _maxWeight;
    public int MaxWeight
    {
        get 
        {
            return this._maxWeight;
        }
        set 
        {
            if (this._maxWeight != value)
            {
                this._maxWeight = value;
                this.OnPropertyChanged("MaxWeight");
            }
        }
    }

    public IEnumerable<int> ComboBoxItems
    {
        get
        {
            yield return 123;
            yield return 567;
            yield return 999;
            yield return 567;
            yield return 1999;
            yield return 5767;
            yield return 9990;
        }
    }
}
因此,现在我们有了一个带有必要属性声明的表示模型,让我们看看视图:

<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:self ="clr-namespace:Test"
    Title="MainWindow" 
    Height="350" Width="525">
<Window.Resources>
    <self:NullableBoolToStringConvreter x:Key="nullableBoolToStringConverter" />
</Window.Resources>
<Grid>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label VerticalAlignment="Center">IsFirstChecked:</Label>
            <CheckBox VerticalAlignment="Center"
                      IsChecked="{Binding Path=IsFirstChecked}" />
        </StackPanel>

        <StackPanel Orientation="Horizontal">
            <Label VerticalAlignment="Center">Max Weight:</Label>
            <ComboBox ItemsSource="{Binding Path=ComboBoxItems}" 
                      VerticalAlignment="Center"
                      SelectedValue="{Binding Path=MaxWeight}">
            </ComboBox>
        </StackPanel>

        <TextBox Text="{Binding Path=MaxWeight}" />
        <TextBox Text="{Binding Path=IsFirstChecked, Converter={StaticResource nullableBoolToStringConverter}}"/>

        <Button Click="Button_Click" Content="Reset combo box to 999 and checkbox to null"/>
    </StackPanel>
</Grid>
如您所见,我们在MainWindow构造函数中创建SampleModel实例,设置其属性并设置
<CheckBox IsThreeState="false" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
public bool IsChecked { get; set; }
<ComboBox ItemsSource="{Binding Numbers}" SelectedItem="{Binding SelectedNumber, Mode=TwoWay}"/>
public IEnumerable<int> Numbers { get { return new[] { 1, 2, 3, 4, 5, 6 }; } }

public int? SelectedNumber { get; set; }
Console.WriteLine(SelectedNumber == null
   ? "No number was selected."
   : SelectedNumber + " was selected.);