我在使用 Element Name
绑定(bind) XAML
时遇到了一个奇怪的问题。
一切正常,但是当我用 StackPanel
包围控件和用户控件时,我遇到了绑定(bind)错误。
我将两个用户控件的可见性与两个切换按钮(IsDeadToggle 和 IsNotTransportable)的 IsChecked 属性绑定(bind)在一起,并使用 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是具有以下属性的
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,它又可以工作了……我开始认为这是一个深度问题。但我不明白为什么我的绑定(bind)在特定深度级别不起作用
编辑 2:
如果我删除切换按钮周围的网格,它也不起作用,因此切换是否与用户控件处于同一级别并不重要。
因此有了 VisualTree(WPF Tree WPF Tree Visualizer)一切都很好:
<WrapPanel>
<ItemsControl>
<ItemsPresenter>
<WrapPanel>
<StackPanel>
<!-- List of UC and Toggles-->
这个不行:
<WrapPanel>
<ItemsControl>
<ItemsPresenter>
<WrapPanel>
<StackPanel>
<StackPanel x:Name="BuggedSp">
<!-- List of UC and Toggles-->
最佳答案
我可以看到您的 ToggleButton
,IsDeadToggle
,在 IsChecked
属性上有两种方式绑定(bind)到 Add.Presenter .Customer.IsAlive
数据上下文中的属性。
我还看到您正在尝试将 LabelDatePicker
的 Visibility
属性绑定(bind)到 ToggleButton 的
,使用转换器进行反转,然后将 bool 值转换为 IsChecked
属性System.Windows.Visibility
。
由于 ToggleButton
和 LabelDatePicker
共享相同的数据上下文,我将简单地将 LabelDatePicker
的可见性绑定(bind)到相同的属性数据上下文:
<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
事件,以确保 LabelDatePicker
在 IsDeadToggle
复选框更改其值时得到正确通知以重新绑定(bind)。
有关详细信息,请参阅 MSDN:http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx
通常,我倾向于避免元素到元素的绑定(bind),以支持数据上下文中的公共(public)属性。这种方式更易于测试且不易损坏(如果您更改了源元素的名称 IsDeadToggle
,那么您需要记住更新绑定(bind)目标)。
关于c# - 使用 StackPanel 包围控件时出现元素名称绑定(bind)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23113166/