【问题标题】:WPF is it possible to pass gridname as parameter to checkbox eventWPF是否可以将gridname作为参数传递给复选框事件
【发布时间】:2016-04-08 09:35:46
【问题描述】:

我正在处理一个表单,我必须根据两个复选框禁用或启用控件。在大约 8 个不同的网格中需要此方案。我已经完成了 C# 来禁用/启用控件,并且工作正常。 现在如何在所有 8 个网格中使用相同的方法? 我尝试的第一个选项是获取父网格,但如果它在另一个网格中,则会失败。

我想到的另一个选项是尽可能将网格作为参数传递。 请让我知道它是否可行以及如何。如果有更好的方法来实现这一点,请告诉我。

更新:我忘记提到的一件事是复选框不应该被禁用,而是所有其他控件都应该被禁用,这就是 C# 代码背后的原因。禁用整个网格也不是解决方案。

XAML:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="CatelDemo.Views.Stack"
        Title="Stack" Height="338" Width="644">
    <Grid >
        <TabControl>
            <TabItem Name="TabOne">
                <Grid x:Name="GridOne">
                    <CheckBox x:Name="cbOneGridOne" Checked="cbOne_Checked" Unchecked="cbOne_Checked" />
                    <CheckBox x:Name="cbTwoGridOne" Checked="cbOne_Checked" Unchecked="cbOne_Checked" />
                    <!-- Other controls that should be disable-->
                </Grid>
            </TabItem>
            <TabItem >
                <Grid x:Name="GridTwo">
                    <CheckBox x:Name="cbOneGridTwo" Checked="cbOne_Checked" Unchecked="cbOne_Checked" />
                    <CheckBox x:Name="cbTwoGridTwo" Checked="cbOne_Checked" Unchecked="cbOne_Checked" />
                    <!-- Other controls that should be disable-->
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

C#代码,扩展方法:

public static void DisableAll(this IEnumerable<Control> input, List<String> filter)
        {
            input.Where(c => !filter.Contains(c.Name)).ToList().ForEach(c => c.IsEnabled = false);
        }

        public static void EnableAll(this IEnumerable<Control> input, List<String> filter)
        {
            input.Where(c => !filter.Contains(c.Name)).ToList().ForEach(c => c.IsEnabled = true);
        }

现在在 XAML 代码后面,我希望能够执行以下操作:

private void cbOne_Checked(object sender, RoutedEventArgs e)
        {
            var filter = getFilter();
        var isValid = ValidateChecks();
            var controls = sourceGrid.Children.OfType<Control>();
            if (!isValid)
            {
                controls.DisableAll(filter);
            }
            else
            {
                controls.EnableAll(filter);
            }

        }

【问题讨论】:

  • 您能否附上您目前拥有的 XAML 示例?

标签: c# wpf


【解决方案1】:

您可以设置DataContext MVVM 样式并将网格的enabled 属性绑定到复选框checked 属性。您只需使用Bindings 来检查它们

【讨论】:

  • 我已经实现了这一点,并记得在问题中我说过我希望相同的方法适用于具有不同 DataContexts 的不同网格。也不应该禁用整个网格,而是应该禁用一些控件。
【解决方案2】:

只需将复选框数据绑定到设置IsEnabled-Property 的样式并将该样式用于所有网格:

<UserControl.Resources>
    <Style TargetType={x:Type Grid}>
        <Style.Triggers>
             <MultiDataTrigger>
                  <MultiDataTrigger.Conditions>
                      <Condition Binding="{ElementName=cb1, Path=IsChecked}" Value="True">
                      <Condition Binding="{ElementName=cb2, Path=IsChecked}" Value="True">
                  </MultiDataTrigger.Conditions>
                  <Setter Property="IsEnabled" Value="True" />
             </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<CheckBox x:Name="cb1" />
<CheckBox x:Name="cb2" />

要么直接使用该样式作为资源,要么向其添加 ResourceKey 并在每个网格中显式使用它。我已将样式设置为UserControl,但基本上您可以将该样式设置为Window,或者如果这些复选框可用,甚至可以设置为App 级别 - 如果它们不可用,请将它们的 IsChecked 属性绑定到一个 DataContext 对象您在相应的级别添加。

【讨论】:

    猜你喜欢
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多