0

我在 WPF 中有这个代码 每个新表单都是通过单击 Itemscontrol 的“Add New”来添加的。

事件是 CSLA 调用。

<Menu Grid.Row="0">
        <MenuItem Header="Add New"
                    csla:InvokeMethod.MethodName="AddNew"
                    csla:InvokeMethod.TriggerEvent="Click" />
    </Menu></ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate >
                <DataTemplate.Resources>
                    <FrameworkElement x:Key="ReqProxyElement" DataContext="{Binding}" />
                </DataTemplate.Resources>
                <Grid>
                    <ContentControl Visibility="Collapsed" Content="{StaticResource ReqProxyElement}" />
                    <Grid>
                        <Grid.DataContext>
                            <formviewmodels:ReqViewModel Model="{Binding Source={StaticResource ReqProxyElement}, Path=DataContext}"  />
                        </Grid.DataContext>
                        <formviews:ReqView />
                    </Grid>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

现在在 ReqView 表单中,我有单选按钮的转换器调用。

<Label Grid.Row="10" Grid.Column="0" Content="required"  />
    <StackPanel Orientation="Horizontal" Grid.Row="10" Grid.Column="1" >
        <!--<RadioButton Content="Yes" GroupName="Required" IsChecked="{Binding Model.Required, Converter={StaticResource NullableBooleanToFalseConverter}}"></RadioButton>
        <RadioButton Content="No" GroupName="Required" IsChecked="{Binding Model.Required, Converter={StaticResource ReverseBoolean}}"></RadioButton>-->
        <RadioButton Content="Yes" GroupName="GRequired" ></RadioButton>
        <RadioButton Content="No" GroupName="GRequired" ></RadioButton>
    </StackPanel>

在这种情况下,当我单击 add New 时,ItemsControl 就像野兽的本质一样尝试绑定回 Form 并在转换器调用中进入无限循环。转换器代码如下。

public class ReverseBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool)
        {
            return (!((bool)value));
        }

        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool)
        {
            return (!((bool)value));
        }
        return value;
    }
}

public class NullableBooleanToFalseConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return false;
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

任何人都可以提出一个解决方案,其中转换器不会将代码踢入无限循环。当单击 Add New 时会发生什么情况,如果 Items 控件中已经有一个表单,它会在创建新的空表单之前尝试再次绑定回该表单。绑定返回将单选按钮设置为 true 说如果选择了 true 但然后将其设置为 trus 会在两个转换器之间开始网球比赛,一个转换它,另一个将它转换回来,模型说 No way the value is true 等等直到应用程序遇到堆栈溢出...

我遇到了 WPF 和 MVVM 模式的有趣情况。我正在寻找一个不破坏 MVVM 范式的解决方案。如果可以取消转换器,那也可以。后端调用是 CSLA 重新注册的属性。

谢谢迪伦

4

1 回答 1

0

您只能绑定Yes收音机。由于它的IsChecked属性绑定到您的布尔值,因此当您检查另一个收音机时,布尔值将变为 false。你甚至不需要ReverseConverter这里。

更新:
仅将Yes收音机绑定到您的字段。RadioButton当它们在同一组中时(它们是)是互斥的。当您选择一个时,您会更改另一个。如果您选择No收音机,则 yes 将被取消选中,Requiredfalse.

至于初始值,如果设置No为false,就会被选中。并且由于Yesis bound to Required,它将节省您的价值。做这样的事情:

<RadioButton Content="Yes" GroupName="GRequired" IsChecked="{Binding Required}"/>
<RadioButton Content="No" GroupName="GRequired" IsChecked="False"/>

更新二:
WPF 中的绑定机制将两个值联系在一起,因此当一个值更改另一个值时,它也可以双向工作。RadioButton.IsCheck只是一个 bool 属性,因此当它的值更改时,它会更改它绑定到的值(在这种情况下Required)。当你检查时No,你也取消检查Yes,它的IsChecked属性会改变。那会改变Required
有关数据绑定的更多信息,请参阅:http: //msdn.microsoft.com/en-us/library/ms752347.aspx

所以,你看,你不需要ReverseConverter, 因为你不需要绑定No任何东西。事实上,您甚至不需要NullBooleanConverter.,因为 WPF 已经知道如何转换bool?bool.

问候,
约尼

于 2013-08-21T15:34:55.990 回答