我已经创建了一个自定义控件,用于在我的应用程序中选择状态,称为StateSelector。如果我将它放在我的UserControl并绑定ItemsSource(通过名为StateList的自定义属性),它工作正常。但是在DataTemplate中使用相同的绑定不起作用。
这是我的StateSelector.xaml
<UserControl x:Class="MyNamespace.StateSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Local="clr-namespace:MyNamespace"
Height="21" Width="60">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
Name="cboState"
SelectedItem="{Binding Path=CurrentState, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
ItemsSource="{Binding Path=StateList, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Code}" />
<TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</UserControl>
这是我的StateSelector.xaml.cs
public class StateSelector : UserControl
{
public ObservableCollection<State> StateList
{
get { return (ObservableCollection<State>)GetValue(StateListProperty); }
set { SetValue(StateListProperty, value); }
}
public static readonly DependencyProperty StateListProperty =
DependencyProperty.Register("StateList", typeof(ObservableCollection<State>), typeof(StateSelector));
public State CurrentState
{
get{ return (State)GetValue(CurrentStateProperty); }
set{ SetValue(CurrentStateProperty, value); }
}
public static DependencyProperty CurrentStateProperty =
DependencyProperty.Register("CurrentState", typeof(State), typeof(StateSelector));
/// <summary>
/// Default constructor for StateSelector
/// </summary>
public StateSelector()
{
InitializeComponent();
}
}
然后在包含UserControl的构造函数中,我使用State对象填充ObservableCollection。 这是MyDisplay.xaml.cs
public class MyDisplay : UserControl
{
private static DependencyProperty StateListProperty =
DependencyProperty.Register("StateList", typeof(ObservableCollection<State>), typeof(RateTableDisplay));
public ObservableCollection<State> StateList
{
get{ return (ObservableCollection<State>)GetValue(StateListProperty); }
set{ SetValue(StateListProperty, value); }
}
// Code to define SourceObject as seen in following XAML omitted
public MyDisplay()
{
InitializeComponent();
StateManager stateManager = new StateManager();
StateList = new ObservableCollection<State>(stateManager.GetAll(Context));
}
}
在MyDisplay的XAML中,我有一个部分,它按原样使用StateSelector,另一个部分在DataTemplate中使用它。 这是MyDisplay.xaml
<UserControl x:Class="MyNamespace.MyDisplay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Local="clr-namespace:MyNamespace"
Height="Auto" Width="Auto"
Name="_this"
DataContext="{Binding ElementName=_this, Path=SourceObject}">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate x:Key="OriginStateCellTemplate">
<Local:StateSelector StateList="{Binding ElementName=_this, Path=StateList}" />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<!-- Unrelated XAML omitted -->
<!-- The StateSelector below gets populated properly -->
<StackPanel>
<Local:StateSelector Grid.Column="3" StateList="{Binding ElementName=_this, Path=StateList}" x:Name="cmbMasterOriginState" />
</StackPanel>
<!-- More Unrelated XAML omitted -->
<!-- The StateSelector below does not get populated at all -->
<StackPanel>
<ListView Height="610">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn x:Name="origStateCol" Width="85" CellTemplate="{StaticResource OriginStateCellTemplate}">
<GridViewColumnHeader Click="header_Click" Tag="OriginState">Origin State</GridViewColumnHeader>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</UserControl>
我尝试过不同的方法来绑定StateList,例如:
StateList="{Binding Path=StateList, Source={x:Reference _this}}"
StateList="{Binding Path=StateList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
但没有这样的运气。我无法弄清楚为什么没有在DataTemplate示例中填充ItemsSource。它在DataTemplate之外工作正常。我在Visual Studio的调试输出中也没有遇到任何绑定错误。
搜索时我发现了很多相关问题,但他们似乎都在尝试使用顶级UserControl元素中定义的通用DataContext。我特意尝试使用UserControl本身的属性。
有什么想法吗?
答案 0 :(得分:2)
在INotifyPropertyChanged
中实施UserControl
,然后为StateList
创建属性,然后在setter上提升INotifyPropertyChanged
提供的属性更改事件。