.net - XAML 正在使用先前的绑定(bind)调用 get

标签 .net wpf binding

XAML 正在使用新绑定(bind)的值调用先前绑定(bind)的 set

调用堆栈

Gabe2a.exe!Gabe2a.GabeLib.SearchItem.ParenRight1.set(bool value) Line 24333 C#
[External Code] 
Gabe2a.exe!Gabe2a.PageSearch.NotifyPropertyChanged(string info) Line 34 C#

searchItemCur 正确

protected void NotifyPropertyChanged(String info)
{
    if (PropertyChanged != null)
    {
        Debug.WriteLine("PageSearch NotifyPropertyChanged " + info);
        if ( info == "SearchItemCur"  && searchItemCur != null)
            Debug.WriteLine("   searchItemCur " + searchItemCur.FieldDef.DispName);
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

下面是在错误的对象上调用的
识别的FieldDef.DispName错误
使用新值在旧绑定(bind)上调用它

public Boolean ParenRight3
{
    get { return parenRight3; }
    set
    {
        if (parenRight3 == value) return;
        Debug.WriteLine("ParenRight3 " + value.ToString() + " " + FieldDef.DispName);
        if (value && (AndOr == enumAndOr.Except || AndOr == enumAndOr.NotYetDefined)) return;
        parenRight3 = value;

我已经查到了
它在 [外部代码] 处中断,我很确定是 XAML
该行正在使用新绑定(bind)的值调用旧绑定(bind)
将新绑定(bind)的值分配给绑定(bind)会导致错误的值
如果旧的和新的都具有相同的值,则根本不需要调用 get

Gabe2a.exe!Gabe2a.GabeLib.SearchItem.ParenRight1.set(bool value) Line 24333 C#
[External Code] 
Gabe2a.exe!Gabe2a.PageSearch.NotifyPropertyChanged(string info) Line 34 C#

这是绑定(bind)

<RadioButton Style="{StaticResource RadioButton03}" FontSize="14" Content=")"
            IsChecked="{Binding  ElementName=_this, Path=SearchItemCur.ParenRight1}"/>

有一个单独的DataContext

最佳答案

正如评论中提到的,单选按钮和绑定(bind)以一些有趣的方式交互,因为组内交互会自动设置其他单选按钮上的 IsChecked。我在处理作为数据模板一部分的单选按钮时遇到了这个问题。当您更改 DataContext 时,它将重用为模板创建的可视化树,但随后将更改的 DataContext 传播到内部的所有单选按钮。这会导致与您在绑定(bind)中使用嵌套路径观察到的结果相同。

这是一个复选框样式,已重新模板化,看起来像单选按钮。这缺少一些样式资源,但是您可以对其进行一些修改以适用于您的应用程序使用的任何样式。注意“IsHitTestVisible”黑客;它用于防止用户“取消选中”应该充当单选按钮的复选框。

<Style x:Key="RadioCheckBox" TargetType="{x:Type CheckBox}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="FocusVisualStyle" Value="{DynamicResource RadioButtonFocusVisual}" />
    <Setter Property="Background" Value="{DynamicResource CheckBoxBg}" />
    <Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}" />
    <Setter Property="Template" Value="{DynamicResource NuclearRadioCheckBox}" />
    <Setter Property="IsHitTestVisible" Value="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={StaticResource InvBool}}"/>
</Style>

<ControlTemplate x:Key="NuclearRadioCheckBox" TargetType="{x:Type CheckBox}">
    <BulletDecorator Background="Transparent">
        <BulletDecorator.Bullet>
            <Grid Width="13" Height="13">
                <Ellipse x:Name="Ellipse_Border" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1" />
                <Ellipse x:Name="InnerBorder" StrokeThickness="1" Stroke="{DynamicResource CheckBoxInnerBorderBrush}" Margin="2" />
                <Ellipse Margin="3" x:Name="CheckMark" Stroke="#FFAA5B0B">
                    <Ellipse.Fill>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FFFFFFAF" Offset="0" />
                            <GradientStop Color="#FFFE9E45" Offset="1" />
                            <GradientStop Color="#FFFFE38A" Offset="0.325" />
                            <GradientStop Color="#FFFFBA61" Offset="0.663" />
                        </LinearGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
            </Grid>
        </BulletDecorator.Bullet>
        <ContentPresenter RecognizesAccessKey="True" Margin="5,0,0,0" HorizontalAlignment="Left" />
    </BulletDecorator>

    <ControlTemplate.Triggers>
        <Trigger Property="IsChecked" Value="false">
            <Setter Property="Visibility" Value="Collapsed" TargetName="CheckMark" />
        </Trigger>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Fill" Value="{DynamicResource MouseOverBrush}" TargetName="Ellipse_Border" />
            <Setter Property="Stroke" TargetName="InnerBorder" Value="{DynamicResource CheckBoxInnerBorderHoverBrush}" />
            <Setter Property="Stroke" TargetName="Ellipse_Border" Value="{DynamicResource CheckBoxHoverBorderBrush}" />
        </Trigger>
        <Trigger Property="IsPressed" Value="true">
            <Setter Property="Fill" Value="{DynamicResource PressedBrush}" TargetName="Ellipse_Border" />
            <Setter Property="Stroke" Value="{DynamicResource GlyphBrush}" TargetName="Ellipse_Border" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Fill" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Ellipse_Border" />
            <Setter Property="Stroke" Value="#40000000" TargetName="Ellipse_Border" />
            <Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}" />
        </Trigger>

    </ControlTemplate.Triggers>
</ControlTemplate>

关于.net - XAML 正在使用先前的绑定(bind)调用 get,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26347800/

相关文章:

c# - 按键盘上的删除键时无法自动更新文本框的总值

.net - NUnit、MSTest 等之间真的有什么区别吗?

wpf - 与 ThemeResourceKey 关联的颜色

c# - 根据编辑状态在 XAML DataGrid 中设置行背景颜色

wpf - 如何强制 MarkupExtension 再次绑定(bind)

wpf - 如何TemplateBind到BorderThickness.Top(或Bottom或Left或Right)?

c# - .NET Regex.Matches 在找到包含 * () 的模式的多个匹配项时行为不符合预期

c# - 远离数据库实现事务有什么缺点?

WPF:从数据上下文对象中获取 DataTemplate 元素

c++ - 使用 Lua C API 将现有的 C 变量绑定(bind)到 Lua