我正在构建我所学到的基本上是一个手风琴控件,其选择模式确保当时只有一个部分是打开的。每个部分都使用Expander控件实现,因此如果打开Expander,其他所有部分都应该关闭。
我以下列方式做到了:
虽然转换器方法成功执行,但问题是DependencyProperty ControlValue 从未设置,即使它成功绑定到某个值并且不会引发任何错误。我通过各种调试证实了这一点。因此结果是所有部分都停留在默认值上,呈现我想要的手风琴选择行为,没用。
为什么要忽略DependencyProperty绑定?是因为它是在绑定中定义的,还是其他什么?
说明
一切都是数据驱动的,并且在实现通用数据驱动版本之前我在静态模型中工作得很好。完全数据驱动的解决方案是必须的,因此使用单向多绑定或硬编码的XAML参数(我能够找到相关问题的解决方案)不是一种选择。
重要的是要注意所有其他绑定都是完美的,因此DataContext没有问题。因为一切都应该工作(在我看来),这也是我尚未采用WPF Toolkit Accordion方式的原因,所以请不要在最初提出这个建议(除非它真的是唯一的方法)。首先,作为WPF的新手,我想了解为什么这不起作用。
XAML(摘录 - 某些名称更改为混淆业务含义 - 中心部分是 IsExpanded 绑定):
<ItemsControl ItemsSource="{Binding QuestionSection.QuestionAssignments}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Style="{x:Null}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{StaticResource Grey400Brush}"
BorderThickness="0 1 0 0">
<Expander Background="{StaticResource Grey200Brush}"
Foreground="Black"
Padding="0"
Margin="0">
<Expander.IsExpanded>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=views:TypeOfParentControl}"
Path="DataContext.ActiveQuestionId"
Mode="TwoWay">
<Binding.Converter>
<converters:TestConverter ControlValue="{Binding QuestionId}"/>
</Binding.Converter>
</Binding>
</Expander.IsExpanded>
<Expander.HeaderTemplate>
<!--Custom Styling Here, All Bindings Work-->
</Expander.HeaderTemplate>
<!--Content Here, All Bindings Work-->
</Expander>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
转换器(简化)
public class TestConverter : DependencyObject, IValueConverter
{
public static readonly DependencyProperty ControlValueProperty = DependencyProperty.Register("ControlValue", typeof(short), typeof(TestConverter), new PropertyMetadata(default(short)));
public short ControlValue
{
get { return (short) GetValue(ControlValueProperty); }
set { SetValue(ControlValueProperty, value); }
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (short)value==ControlValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? ControlValue : Binding.DoNothing;
}
}
ViewModel中的ActiveQuestionId实现 - INotifyPropertyChanged已经过测试并且有效,ViewModel是父UserControl上的DataContext
private short activeQuestionId;
public short ActiveQuestionId
{
get
{
return activeQuestionId;
}
set
{
if (value != activeQuestionId)
{
activeQuestionId = value;
OnPropertyChanged();
}
}
}
答案 0 :(得分:2)
当前的DataContext值不会继承到TestConverter实例。
您可以完全避免这种复杂的绑定,并使用ListBox实现您的控制:
<ListBox ItemsSource="{Binding QuestionSection.QuestionAssignments}"
SelectedValuePath="QuestionId"
SelectedValue="{Binding ActiveQuestionId}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Expander IsExpanded="{Binding IsSelected,
RelativeSource={RelativeSource TemplatedParent}}">
...
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>