C# DataTemplate中的WPF ItemsSource绑定

C# DataTemplate中的WPF ItemsSource绑定,c#,wpf,xaml,C#,Wpf,Xaml,我创建了一个自定义控件,用于在应用程序中选择状态,称为StateSelector。如果我将它放在UserControl中并绑定ItemsSource(通过名为StateList的自定义属性),它就可以正常工作。但是在DataTemplate中使用相同的绑定不起作用 这是我的StateSelector.xaml <UserControl x:Class="MyNamespace.StateSelector" xmlns="http://schemas.microsoft.com/wi

我创建了一个自定义控件,用于在应用程序中选择状态,称为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>
但没有这样的运气。我不明白为什么DataTemplate示例中没有填充ItemsSource。它在DataTemplate之外工作正常。在VisualStudio中调试的输出中也没有任何绑定错误

在搜索时,我发现了很多相关的问题,但它们似乎都试图使用在顶级UserControl元素中定义的通用DataContext。我特别尝试使用UserControl本身的一个属性


有什么想法吗?

UserControl
中实现
INotifyPropertyChanged
,然后为
StateList
创建属性,然后在setter上引发由
INotifyPropertyChanged

提供的属性更改事件,您似乎绑定到了一个名为“
SourceObject
”的东西在你的控制之下。我看不出你在哪里定义了它。另外,为什么不绑定控件的
DataContext
?顺便说一句,辅助控件的DataContext意味着您不必在XAML中处理控件的DataContext绑定。我会将DataContext分配给SourceObject,这是此表单关注的对象。因此,我的大多数绑定都非常简单。我希望将此特定的“状态选择器”绑定到MyDisplay的属性,而不是MyDisplay.SourceObject的属性。我尝试在MyDisplay for StateList上实现此操作,但没有任何帮助。将我的StateList属性设置为DependencyProperty是否不够?另外,请您解释一下,当非模板控件的绑定可以工作时,为什么我需要INotifyPropertyChanged来解决DataTemplate内部绑定的问题?不,如果您希望依赖项属性可以为您的ViewModel绑定,您可以创建它们。您正在实际用户控件代码(即视图)后面创建属性。它可以访问您的控件的位置。做绑定首先有什么意义?为什么不直接将
itemsource
设置为
StateList
您的意思是以编程方式设置statescholector的itemsource?我正在尽我所能在WPF中做更多的事情。但无论如何,它仍然无法解释为什么绑定在DataTemplate外部工作,而不是在DataTemplate内部工作。因为数据模板是稍后执行的,所以控件看起来可以工作,但实际上它能够获取属性的值。你需要
INPC
告诉UI“嘿,有一个新值,更新你的值”我是个白痴。有一些代码在后台操纵CellTemplate。这个问题与约束毫无关系。我在自己的帖子上打了个标记,问应该怎么做。我想删除它,因为这个问题是骗人的,但你的答案绝对正确。我会接受的,看看mods怎么说。谢谢你的帮助:)
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();
    }
}
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));
    }
}
<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="{Binding Path=StateList, Source={x:Reference _this}}"
StateList="{Binding Path=StateList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"