WPF:从用户控件到 ViewModel 的绑定属性
WPF: Binding Property from User Control to ViewModel
我有一个名为 AntecedentControl 的用户控件:
XAML:
<UserControl x:Name="AntecedentUserControl">
<ScrollViewer DataContext="{Binding ElementName=AntecedentUserControl}">
<telerik:RadGridView ItemsSource="{Binding Path=AntecedentList}"
AutoGenerateColumns="False"
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
Header="Seccion"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Group, Mode=TwoWay}"
Header="Grupo"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Tome, Mode=TwoWay}"
Header="Tomo"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Volume, Mode=TwoWay}"
Header="Volumen"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Inscription, Mode=TwoWay}"
Header="Inscripcion"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Bis, Mode=TwoWay}"
Header="Bis"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewColumn>
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<telerik:RadButton Content="Delete"
Command="telerikGrid:RadGridViewCommands.Delete"
CommandParameter="{Binding}"/>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</ScrollViewer>
代码隐藏(C#):
public partial class AntecedentControl : UserControl
{
public ObservableCollection<Antecedent> AntecedentList
{
get { return (ObservableCollection<Antecedent>)GetValue(AntecedentListProperty); }
set { SetValue(AntecedentListProperty, value); }
}
public static readonly DependencyProperty AntecedentListProperty =
DependencyProperty.Register("AntecedentList",
typeof(ObservableCollection<Antecedent>),
typeof(AntecedentControl),
new FrameworkPropertyMetadata(new ObservableCollection<Antecedent>(), OnListPropertyChanged));
private static void OnListPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var antecedentList = source as AntecedentControl;
var value = e.NewValue as ObservableCollection<Antecedent>;
antecedentList.AntecedentList = value;
}
public AntecedentControl()
{
InitializeComponent();
}
}
并且,在单独的视图中,我调用此 UserControl,如下所示:
<DomainTransmissionControls:AntecedentControl AntecedentList="{Binding ElementName=AntecedentUserControl, Path=Antecedents, Mode=TwoWay}"/>
在这个单独视图的 ViewModel 上,我有一个名为 'Antecedents':
的属性
public ObservableCollection<Antecedent> Antecedents { get; set; }
简单来说:AntecedentControl UC 是一个网格,它有一个方法,您可以在所述网格上 add/edit 项目。当前 UC 的属性 'AntecedentList' 是列表所在的位置 'saved'。
调用'AntecedentControl'的另一个UC的ViewModel的属性'Antecedents'应该绑定到AntecedentControl UC的'AntecedentList'。
我想知道如何将 ViewModel 上的这个属性绑定到在单独的 UserControl (AntecedentControl) 中找到的 'AntecedentList' 属性,因为当前代码 returns null。
我认为我在 AntecedentControl UC 上的 DependencyProperty 声明有问题,因为在 'OnListPropertyChanged' 方法上放置断点显示 e.NewValue 正在返回 null。
如果是,为什么不返回 Dependency Property 语句中声明的默认值?
感谢您的宝贵时间。
您的绑定似乎不正确。您似乎正在尝试访问您创建的 UserControl 中的元素 (AntecedentUserControl)?
除非您为了简单起见而省略了一些代码,否则实际上您似乎甚至不需要 DependencyProperty?有什么原因不能设置 DataContext 吗?
SomeView.xaml
<DomainTransmissionControls:AntecedentControl DataContext="{Binding Antecedents}" />
SomeViewModel.cs
private ObservableCollection<Antecedent> _antecedents;
public ObservableCollection<Antecedent> Antecedents
{
get
{
if (_antecedents == null)
_antecedents = new ObservableCollection<Antecedent>();
return _antecedents;
}
}
AntecedentControl.xaml
<UserControl>
<ScrollViewer>
<telerik:RadGridView ItemsSource="{Binding}" AutoGenerateColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
Header="Seccion" IsFilterable="False" IsVisible="True" />
<!-- Additional column definitions. -->
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</ScrollViewer>
</UserControl>
AntecedentControl.xaml.cs
public partial class AntecedentControl : UserControl
{
public AntecedentControl()
{
InitializeComponent();
}
}
我有一个名为 AntecedentControl 的用户控件:
XAML:
<UserControl x:Name="AntecedentUserControl">
<ScrollViewer DataContext="{Binding ElementName=AntecedentUserControl}">
<telerik:RadGridView ItemsSource="{Binding Path=AntecedentList}"
AutoGenerateColumns="False"
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
Header="Seccion"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Group, Mode=TwoWay}"
Header="Grupo"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Tome, Mode=TwoWay}"
Header="Tomo"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Volume, Mode=TwoWay}"
Header="Volumen"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Inscription, Mode=TwoWay}"
Header="Inscripcion"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Bis, Mode=TwoWay}"
Header="Bis"
IsVisible="True"
IsFilterable="False"/>
<telerik:GridViewColumn>
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<telerik:RadButton Content="Delete"
Command="telerikGrid:RadGridViewCommands.Delete"
CommandParameter="{Binding}"/>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</ScrollViewer>
代码隐藏(C#):
public partial class AntecedentControl : UserControl
{
public ObservableCollection<Antecedent> AntecedentList
{
get { return (ObservableCollection<Antecedent>)GetValue(AntecedentListProperty); }
set { SetValue(AntecedentListProperty, value); }
}
public static readonly DependencyProperty AntecedentListProperty =
DependencyProperty.Register("AntecedentList",
typeof(ObservableCollection<Antecedent>),
typeof(AntecedentControl),
new FrameworkPropertyMetadata(new ObservableCollection<Antecedent>(), OnListPropertyChanged));
private static void OnListPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var antecedentList = source as AntecedentControl;
var value = e.NewValue as ObservableCollection<Antecedent>;
antecedentList.AntecedentList = value;
}
public AntecedentControl()
{
InitializeComponent();
}
}
并且,在单独的视图中,我调用此 UserControl,如下所示:
<DomainTransmissionControls:AntecedentControl AntecedentList="{Binding ElementName=AntecedentUserControl, Path=Antecedents, Mode=TwoWay}"/>
在这个单独视图的 ViewModel 上,我有一个名为 'Antecedents':
的属性public ObservableCollection<Antecedent> Antecedents { get; set; }
简单来说:AntecedentControl UC 是一个网格,它有一个方法,您可以在所述网格上 add/edit 项目。当前 UC 的属性 'AntecedentList' 是列表所在的位置 'saved'。
调用'AntecedentControl'的另一个UC的ViewModel的属性'Antecedents'应该绑定到AntecedentControl UC的'AntecedentList'。
我想知道如何将 ViewModel 上的这个属性绑定到在单独的 UserControl (AntecedentControl) 中找到的 'AntecedentList' 属性,因为当前代码 returns null。
我认为我在 AntecedentControl UC 上的 DependencyProperty 声明有问题,因为在 'OnListPropertyChanged' 方法上放置断点显示 e.NewValue 正在返回 null。
如果是,为什么不返回 Dependency Property 语句中声明的默认值?
感谢您的宝贵时间。
您的绑定似乎不正确。您似乎正在尝试访问您创建的 UserControl 中的元素 (AntecedentUserControl)?
除非您为了简单起见而省略了一些代码,否则实际上您似乎甚至不需要 DependencyProperty?有什么原因不能设置 DataContext 吗?
SomeView.xaml
<DomainTransmissionControls:AntecedentControl DataContext="{Binding Antecedents}" />
SomeViewModel.cs
private ObservableCollection<Antecedent> _antecedents;
public ObservableCollection<Antecedent> Antecedents
{
get
{
if (_antecedents == null)
_antecedents = new ObservableCollection<Antecedent>();
return _antecedents;
}
}
AntecedentControl.xaml
<UserControl>
<ScrollViewer>
<telerik:RadGridView ItemsSource="{Binding}" AutoGenerateColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Section, Mode=TwoWay}"
Header="Seccion" IsFilterable="False" IsVisible="True" />
<!-- Additional column definitions. -->
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</ScrollViewer>
</UserControl>
AntecedentControl.xaml.cs
public partial class AntecedentControl : UserControl
{
public AntecedentControl()
{
InitializeComponent();
}
}