问题
I have created a user control with collection property:
public static readonly DependencyProperty
MyListProperty = DependencyProperty.Register(
"MyList",
typeof(ObservableCollection<Test>),
typeof(UserControl1),
new FrameworkPropertyMetadata(new ObservableCollection<Test>())
);
public ObservableCollection<Test> MyList
{
get { return (ObservableCollection<Test>)base.GetValue(MyListProperty); }
set { base.SetValue(MyListProperty, value); }
}
public static readonly DependencyProperty
BProperty = DependencyProperty.Register(
"B",
typeof(string),
typeof(UserControl1),
new FrameworkPropertyMetadata(null)
);
public string B
{
get { return (string)base.GetValue(BProperty); }
set { base.SetValue(BProperty, value); }
}
The Test class is:
public class Test : DependencyObject
{
public static readonly DependencyProperty
AProperty = DependencyProperty.Register(
"A",
typeof(string),
typeof(Test),
new FrameworkPropertyMetadata(null)
);
public string A
{
get { return (string)base.GetValue(AProperty); }
set { base.SetValue(AProperty, value); }
}
}
Then, i'm trying to use my control for binding:
<TextBox x:Name="tb1" Text="def"/>
<my:UserControl1 x:Name="uc1" B="{Binding ElementName=tb1, Path=Text}">
<my:UserControl1.MyList>
<my:Test A="{Binding ElementName=tb1, Path=Text}"></my:Test>
<my:Test A="100"></my:Test>
</my:UserControl1.MyList>
</my:UserControl1>
The first binding (with B property of User Control) works correctly. The problem is with second binding (with A property of Test which is MyList element). When debugging i have two items in MyList but the A property of the first one is null. Please tell me what I am missing here?
回答1:
The problem here is, that the Binding to ElementName=tb1 can not be resolved, even it will never be evaluated. A Binding to an ElementName is resolved for DependencyObjects which are in the visual or logical Tree of a WPF Application. Adding items to your ObservableCollection (MyList) only means adding the items to the Collection, but not into the Visual Tree.
Edit: Here is the approach discussed in the comments:
In your Window/Page:
<Window.Resources>
<!-- Declare the ViewModel as Resource -->
<my:ViewModel x:Key="viewModel">
<my:ViewModel.MyList>
<my:Test A="Hello sweet" />
<my:Test A="ViewModel" />
</my:ViewModel.MyList>
</my:ViewModel>
</Window.Resources>
<!-- Assign Ressource as DataContext -->
<StackPanel DataContext="{StaticResource viewModel}">
<TextBox x:Name="tb1" Text="def"/>
<!-- Reference your list within the ViewModel -->
<ListBox ItemsSource="{Binding Path=MyList}">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- Bind your property -->
<TextBlock Text="{Binding Path=A}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
And the implementation of ViewModel:
public class ViewModel
{
public ViewModel()
{
this.MyList = new ObservableCollection<Test>();
}
public ObservableCollection<Test> MyList { get; set; }
}
Of course, class Test no longer needs to implement a DependencyObject. Simple get/set Properties are okay.
来源:https://stackoverflow.com/questions/12528286/binding-to-user-controls-collection-property-items-in-xaml