C# 使用StackPanel包围控件时元素名称绑定错误
我在C# 使用StackPanel包围控件时元素名称绑定错误,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,我在XAML和元素名的绑定中遇到了一个奇怪的问题 一切正常,但当我用StackPanel包围控件和用户控件时,我得到了一个绑定错误 我使用两个togglebuttons(IsDeadToggle和IsNotTransportable)的IsChecked属性绑定两个UserControl的可见性,并使用ElementName <ItemsControl AlternationCount="100" FocusVisualStyle="{x:Null}" HorizontalAlignmen
XAML
和元素名的绑定中遇到了一个奇怪的问题
一切正常,但当我用StackPanel
包围控件和用户控件时,我得到了一个绑定错误
我使用两个togglebuttons(IsDeadToggle和IsNotTransportable)的IsChecked属性绑定两个UserControl的可见性,并使用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>
错误:
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:
如果我删除第一个SP StackPanel,它将再次工作。。。我开始认为这是一个深度问题。但我不明白为什么我的绑定不能在特定的深度级别工作
编辑2:
如果我删除切换按钮周围的网格,它也不起作用,因此切换是否与usercontrol处于同一级别并不重要
因此,有了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
属性与Add.Presenter.Customer.IsAlive
属性之间具有双向绑定
我还可以看到,您正在尝试将LabelDatePicker
的可见性
属性绑定到ToggleButton
的IsChecked
属性,使用转换器进行反转,然后将bool值转换为System.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
object)将需要实现System.ComponentModel.INotifyPropertyChanged
和IsAlive
属性将需要使用属性名称引发PropertyChanged
事件,以确保在IsDeadToggle
复选框更改其名称时正确通知LabelDatePicker
重新绑定价值观
有关更多信息,请参阅MSDN:
通常,我倾向于避免元素到元素的绑定,而在数据上下文中使用公共属性。这种方式更易于测试,也不太脆弱(就像您更改了源元素的名称,IsDeadToggle
,那么您需要记住更新绑定目标)。不确定这是否会产生任何影响,但您是否尝试过使用name而不是x:name?我读到了一些差异,基本上我会说问题在于视觉树。查看此链接:@sexta13控件不在DataTemplate/ControlTemplate
@kenjara试图替换x:name但无效谢谢!!成功了!将来我将尽可能多地绑定到datacontext中的道具。然而,我不明白为什么ElementName不能在特定的深度级别工作,但我同意使用DataContext更容易阅读。。。
<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" />