使用StackPanel包围控件时的元素名称绑定错误

时间:2014-04-16 15:01:16

标签: c# wpf xaml binding

我在XAMLElement Name绑定时遇到了一个奇怪的问题。

一切正常但是当我用StackPanel包围控件和用户控件时,我得到了绑定错误。

我将两个用户控件的可见性与两个togglebuttons(IsDeadToggle和IsNotTransportable)的IsChecked属性绑定并使用ElementName。

<ItemsControl AlternationCount="100" FocusVisualStyle="{x:Null}" HorizontalAlignment="Left">
                        <ItemsControl.ItemsSource>
                            <CompositeCollection>
                                <StackPanel x:Name="FirstSP" Margin="0,0,10,0">
                                    <TextBlock FocusVisualStyle="{x:Null}"
                                               Style="{StaticResource WrapTitleAddTextBlock}"
                                               Text="{x:Static languages:ResCommon.General}" />
                                    <StackPanel x:Name="BuggedSP" Background="{StaticResource WrapBackground}">
                                        <StackPanel Orientation="Horizontal"
                                                    Margin="10,20">
                                            <RadioButton Content="{x:Static languages:ResCommon.Man}"
                                                         IsChecked="{Binding Path=Add.Presenter.Customer.Gender, Mode=TwoWay, Converter={StaticResource EnumMatchToBooleanConverter}, ConverterParameter=Male}" />
                                            <RadioButton x:Name="IsWoman"
                                                         Content="{x:Static languages:ResCommon.Woman}"
                                                         IsChecked="{Binding Path=Add.Presenter.Customer.Gender,
                                                                             Mode=TwoWay,
                                                                             Converter={StaticResource EnumMatchToBooleanConverter},
                                                                             ConverterParameter=Female}" />
                                        </StackPanel>
                                        <formElement:LabelComboBox Margin="{StaticResource ControlAddMargin}"
                                                                   Visibility="{Binding Add.Presenter.Customer.CustomerIdInsured, Converter={StaticResource NullToVisibilityConverter}}"
                                                                   LabelName="{x:Static languages:ResCommon.BeneficiaryType}"
                                                                   ComboBoxDisplayMemberItem="Translation"
                                                                   ComboBoxSelectedValueItem="Enum"
                                                                   ComboBoxItems="{Binding Source={me:EnumValues EnumType=entities:TypeOfBeneficiary, ResourceName='Languages.ResEnum,Languages'}}"
                                                                   ComboBoxSelectedItem="{Binding Add.Presenter.Customer.TypeOfBeneficiary}" />
                                        <formElement:InnerLabelBox Margin="{StaticResource ControlAddMargin}"
                                                                   LabelName="{x:Static languages:ResCommon.LastName}"
                                                                   TextBoxValue="{Binding Add.Presenter.Customer.LastName,
                                                                                 Converter={StaticResource StringToUpperStringConverter},
                                                                                 Mode=TwoWay,
                                                                                 ValidatesOnDataErrors=true,
                                                                                 NotifyOnValidationError=true}" />
                                        <formElement:LabelBox Margin="{StaticResource ControlAddMargin}"
                                                              LabelName="{x:Static languages:ResCommon.MaidenName}"
                                                              TextBoxValue="{Binding Add.Presenter.Customer.MaidenName,
                                                                                 Converter={StaticResource StringToUpperStringConverter},
                                                                                 Mode=TwoWay,
                                                                                 ValidatesOnDataErrors=true,
                                                                                 NotifyOnValidationError=true}"
                                                              Visibility="{Binding IsChecked,
                                                                               ElementName=IsWoman,
                                                                               Converter={StaticResource BooleanToVisibilityConverter}}" />
                                        <formElement:InnerLabelBox Margin="{StaticResource ControlAddMargin}"
                                                                   LabelName="{x:Static languages:ResCommon.FirstName}"
                                                                   TextBoxValue="{Binding Add.Presenter.Customer.FirstName,
                                                                                 Converter={StaticResource StringToCapitalizeStringConverter},
                                                                                 Mode=TwoWay,
                                                                                 ValidatesOnDataErrors=true,
                                                                                 NotifyOnValidationError=true}" />
                                        <resources:DateTimePickerTextBoxSwitch
                                            Margin="{StaticResource ControlAddMargin}"
                                            TextBoxValue="{Binding Add.Presenter.Customer.BirthDateCustom,
                                                                                Mode=TwoWay,
                                                                                ValidatesOnDataErrors=true,
                                                                                NotifyOnValidationError=true}"
                                            DateTimeValue="{Binding Add.Presenter.Customer.BirthDate, Mode=TwoWay}" />
                                        <Grid Width="220" Margin="10,10,10,0">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*"></ColumnDefinition>
                                                <ColumnDefinition Width="60"></ColumnDefinition>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Style="{StaticResource DarkSmallFontStyle}" Text="{x:Static languages:ResCustomers.IsDead}"></TextBlock>
                                            <ToggleButton Grid.Column="1" IsChecked="{Binding Add.Presenter.Customer.IsAlive, Mode=TwoWay}"
                                                          Style="{StaticResource OnOffToggleButton}"
                                                          x:Name="IsDeadToggle" />
                                        </Grid>
                                        <formElement:LabelDatePicker Margin="{StaticResource ControlAddMargin}"
                                                                     DatePickerValue="{Binding Add.Presenter.Customer.DeathDate,
                                                                                           Mode=TwoWay}"
                                                                     LabelName="{x:Static languages:ResCustomers.DeathDate}"
                                                                     Visibility="{Binding IsChecked,
                                                                                      ElementName=IsDeadToggle,
                                                                                      Converter={StaticResource BooleanToVisibilityConverterCustomInvert}}"
                                                                     PrintEnum="WithDate" />
                                        <Grid Width="220" Margin="10,10,10,0">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="*"></ColumnDefinition>
                                                <ColumnDefinition Width="60"></ColumnDefinition>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Style="{StaticResource DarkSmallFontStyle}" Text="{x:Static languages:ResCustomers.IsNoTransportable}"></TextBlock>
                                            <ToggleButton Grid.Column="1" IsChecked="{Binding Add.Presenter.Customer.IsNoTransportable, Mode=TwoWay}"
                                                          Style="{StaticResource OnOffToggleButton}"
                                                          x:Name="IsNotTransportableToggle" />
                                        </Grid>
                                        <formElement:MultiLineTextBox
                                            Margin="{StaticResource ControlAddMargin}"
                                            LabelName="{x:Static languages:ResCustomers.NoTransportComment}"
                                            TextBoxValue="{Binding Add.Presenter.Customer.NoTransportComment,
                                                                                         Mode=TwoWay,
                                                                                         ValidatesOnDataErrors=true,
                                                                                         NotifyOnValidationError=true}"
                                            Visibility="{Binding IsChecked,
                                                                                       ElementName=IsNotTransportableToggle,
                                                                                       Converter={StaticResource BooleanToVisibilityConverterCustom}}" />

                                    </StackPanel>
                                </StackPanel>

添加的StackPanel是具有以下属性的StackPanel

x:name="BuggedSP"

错误

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=IsDeadToggle'. BindingExpression:Path=IsChecked; DataItem=null; target element is 'LabelDatePicker' (Name='UCLabelDatePicker'); target property is 'Visibility' (type 'Visibility')

编辑1:

如果我删除了FirstSP StackPanel它再次起作用......我开始认为这是一个深度问题。但我不明白为什么我的绑定不会在特定的深度级别工作

编辑2:

如果我删除了togglebuttons周围的网格,它也不起作用,所以如果切换与用户控件处于同一级别并不重要。

因此,使用VisualTree(WPF树WPF树可视化工具),一切都很好:

<WrapPanel>
    <ItemsControl>
        <ItemsPresenter>
            <WrapPanel>
                <StackPanel>
                    <!-- List of UC and Toggles-->

有了这个,它不起作用:

<WrapPanel>
    <ItemsControl>
        <ItemsPresenter>
            <WrapPanel>
                <StackPanel>
                    <StackPanel x:Name="BuggedSp">        
                    <!-- List of UC and Toggles-->

1 个答案:

答案 0 :(得分:0)

我可以看到您的ToggleButtonIsDeadToggleIsChecked属性上绑定了数据上下文的Add.Presenter.Customer.IsAlive属性。

我还可以看到您尝试将Visibility的{​​{1}}属性绑定到LabelDatePicker的{​​{1}}属性,使用转换器进行反转,然后将bool值转换为IsChecked

由于ToggleButtonSystem.Windows.Visibility共享相同的数据上下文,我只需将ToggleButton的可见性绑定到数据上下文中的同一属性:

LabelDatePicker

注意:数据上下文(LabelDatePicker对象)需要实现<formElement:LabelDatePicker Margin="{StaticResource ControlAddMargin}" DatePickerValue="{Binding Add.Presenter.Customer.DeathDate, Mode=TwoWay}" LabelName="{x:Static languages:ResCustomers.DeathDate}" Visibility="{Binding Add.Presenter.Customer.IsAlive, Converter={StaticResource BooleanToVisibilityConverterCustomInvert}}" PrintEnum="WithDate" /> Customer属性需要使用属性名称引发System.ComponentModel.INotifyPropertyChanged事件确保在IsAlive复选框更改其值后,PropertyChanged已正确通知重新绑定。

有关详细信息,请参阅MSDN:http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

作为一项规则,我倾向于避免元素到元素的绑定,而是支持数据上下文中的公共属性。这种方式更易测试且更不易碎(就像更改源元素的名称LabelDatePicker一样,那么您需要记住更新绑定目标)。