【问题标题】:Checkbox isEnabled behaviour unable to figure outCheckbox isEnabled 行为无法弄清楚
【发布时间】:2013-09-19 10:03:45
【问题描述】:

我的 WPF 应用程序中有三个 CheckBox,我想要的是根据 ViewModel 中的属性禁用/启用 CheckBox。

<Grid>
    <CheckBox x:Name="cbTest1" Margin="12,341,476,5" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    <CheckBox x:Name="cbTest3" Margin="74,341,414,5" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay }" />
    <CheckBox x:Name="cbTest2" Margin="131,341,359,5" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay }" />
    <Button x:Name="btnClick" Click="btnClick_Click" Margin="231,333,29,5" />
</Grid>

在我的测试应用程序中,我为按钮单击编写了代码

private void btnClick_Click(object sender, RoutedEventArgs e)
    {
        if (_boolProperty == true)
        {
            _boolProperty = false;
            cbTest1.IsEnabled = false;
        }
        else
        {
            _boolProperty = true;
            cbTest1.IsEnabled = true;
        }
    }

奇怪的行为是,如果我评论 cbTest1.IsEnabled = false;cbTest1.IsEnabled = true; 然后 CheckBox es 保持禁用状态,

但只有一个 CheckBox 中的更改说,“cbTest1”的值 true 也会在其他复选框中进行更改。就像cbTest1.IsEnabled = true; 一样,所有三个 CheckBox 都已启用。如果 cbTest1.IsEnabled = false; 则所有三个 CheckBox 都被禁用。

请大家多多指教。为什么会这样?绑定是如何在这里发生的? 还有一个问题,如何将 checkBoxes isEnabled 属性与 viewModel 中的属性绑定?

【问题讨论】:

  • 您将每个 CheckBox 的 IsEnabled 属性双向绑定到名为 BoolProperty 的属性。因此,如果您禁用其中一个,该属性将设置为 false,随后另外两个也将被禁用。阅读 MSDN 上的 Data Binding Overview 文章中的绑定。

标签: c# wpf checkbox


【解决方案1】:
<CheckBox x:Name="cbTest1" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay}" />
<CheckBox x:Name="cbTest3" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay}" />
<CheckBox x:Name="cbTest2" IsEnabled="{Binding Path=BoolProperty, Mode=TwoWay}" />

所有三个复选框都绑定到同一个源,因此无论您做什么,它们都将始终共享相同的状态。此外,您的绑定是双向绑定,因此为一个复选框手动设置 IsEnabled 将使您绑定的基础属性也发生更改,这将再次触发其他两个复选框进行更新。

如果你想拥有不同的状态,你将不得不使用三个不同的属性来绑定。

如何将 checkBoxes isEnabled 属性与 viewModel 中的属性绑定?

您所做的已经是正确的(减去共享属性)。因此,如果您绑定到BoolProperty1BoolProperty2BoolProperty3,并且这些属性中的每一个都存在于您的视图模型中,那么一切都很好。您只需要确保复选框将视图模型作为其数据上下文。这通常通过为父组件(通常是Window 本身)提供数据上下文来实现:

Window window = new MyWindow();
window.DataContext = new MyViewModel();
window.Show();

【讨论】:

    【解决方案2】:

    这是因为您拥有的每个复选框中的 TwoWay 绑定。当您启用其中之一时,它会将相应的视图模型属性设置为 True,并且 TwoWay 绑定也会将其他复选框设置为 True。这就是您遇到此问题的主要原因。

    然后让我们从这些复选框中确定您想要什么。如果要单独更改每个复选框,则每个复选框必须具有三个不同的视图模型属性。否则你的行为是正常的,因为你只绑定到一个 VM 字段。

    <Grid>
        <CheckBox x:Name="cbTest1" Margin="12,341,476,5" IsEnabled="{Binding Path=BoolProperty1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <CheckBox x:Name="cbTest3" Margin="74,341,414,5" IsEnabled="{Binding Path=BoolProperty2, Mode=TwoWay }" />
        <CheckBox x:Name="cbTest2" Margin="131,341,359,5" IsEnabled="{Binding Path=BoolProperty3, Mode=TwoWay }" />
        <Button x:Name="btnClick" Click="btnClick_Click" Margin="231,333,29,5" />
    </Grid>
    

    正如上面提到的@dzavala,您应该修改视图模型属性的值,而不是复选框本身。您应该对按钮单击事件使用命令。阅读此处Commands, RelayCommands and EventToCommandICommand interface

    【讨论】:

    • 如果是纯视图相关的按钮,在视图模型中没有实际意义,那我就不同意了。在这种情况下,最好有一个带有代码隐藏事件处理程序的按钮来更新部分视图本身。
    【解决方案3】:

    不设置私有字段_boolProperty,而是设置属性BoolProperty,并在其设置器中引发PropertyChanged事件。

    【讨论】:

    • 是的,我已经完成了,我还没有发布整个代码,private bool _boolProperty; public bool BoolProperty { get { return _boolProperty; } set { _boolProperty = value; OnPropertyChanged("BoolProperty"); } } 这已经处理好了
    猜你喜欢
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多