将数据上下文绑定到 usecontrol

本文关键字:usecontrol 绑定 上下文 数据 | 更新日期: 2023-09-27 17:55:14

我创建了我的用户控件,并在代码中添加了属性 CompanyName、FirstName 和 SecondName。我为每个属性添加了 DependencyProperty。在xaml中,我使用LongListSelector,我想在ItemTemplate中绑定视图模型中的一些东西:可观察的集合(FirstName和SecondName)和一个字符串(CompanyName)。

由于某种原因,不会触发公司名称的依赖项属性,并且不会绑定值。对于可观察集合,所有内容都已绑定。

注意:我不想绑定 TextBlock 的 Text 属性。这只是一个新项目,我正在尝试解决问题。在实际项目中,我在代码中处理这些属性,然后发生了一些事情。

我会献出我王国的一半和解决这个问题的女儿,因为我几天来都要面对这个问题。

这是示例解决方案

这是代码..

MyUserControl 背后的代码.cs

public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
        this.Loaded += MyUserControl_Loaded;
    }
    private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
    {
        txtCompanyName.Text = CompanyName;
        txtFirstName.Text = FirstName;
        txtSecondName.Text = SecondName;
    }
    public string CompanyName
    {
        get
        {
            return (string)GetValue(CompanyNameProperty);
        }
        set
        {
            SetValue(CompanyNameProperty, value);
        }
    }
    public static DependencyProperty CompanyNameProperty = DependencyProperty.Register("CompanyName", typeof(string), typeof(MyUserControl), new PropertyMetadata("", CompanyNameChanged));
    private static void CompanyNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = d as MyUserControl;
        if (sender == null) return;
        var newValue = e.NewValue as string;
        sender.CompanyName = newValue;
    }
    public string FirstName
    {
        get
        {
            return (string)GetValue(FirstNameProperty);
        }
        set
        {
            SetValue(FirstNameProperty, value);
        }
    }
    public static DependencyProperty FirstNameProperty = DependencyProperty.Register("FirstName", typeof(string), typeof(MyUserControl), new PropertyMetadata("", FirstNameChanged));
    private static void FirstNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = d as MyUserControl;
        if (sender == null) return;
        var newValue = e.NewValue as string;
        sender.FirstName = newValue;
    }
    public string SecondName
    {
        get
        {
            return (string)GetValue(SecondNameProperty);
        }
        set
        {
            SetValue(SecondNameProperty, value);
        }
    }
    public static DependencyProperty SecondNameProperty = DependencyProperty.Register("SecondName", typeof(string), typeof(MyUserControl), new PropertyMetadata("", SecondNameChanged));
    private static void SecondNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sender = d as MyUserControl;
        if (sender == null) return;
        var newValue = e.NewValue as string;
        sender.SecondName = newValue;
    }
}

MainPage.xaml

<phone:PhoneApplicationPage
x:Class="PhoneApp6.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
xmlns:sharecontrols="clr-namespace:PhoneApp6"
x:Name="self">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
        <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>
    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <phone:LongListSelector 
            x:Name="MainLongListSelector" 
            Margin="0,0,-12,0" 
            ItemsSource="{Binding Employees}">
            <phone:LongListSelector.ItemTemplate>
                <DataTemplate>
                    <StackPanel Margin="0,0,0,17">
                        <sharecontrols:MyUserControl 
                            FirstName="{Binding FirstName}"
                            SecondName="{Binding SecondName}"
                            CompanyName="{Binding ElementName=self, Path=DataContext.CompanyName}"
                            />
                    </StackPanel>
                </DataTemplate>
            </phone:LongListSelector.ItemTemplate>
        </phone:LongListSelector>
    </Grid>
</Grid>
</phone:PhoneApplicationPage>

将数据上下文绑定到 usecontrol

我查看了您的示例解决方案,检查并激励了您的代码,最后我实现了您想要的,我发现了几个问题。

  • 代码CompanyName="{Binding ElementName=self, Path=DataContext.CompanyName}"在页面MainPage中,您将公司名称绑定到self(页面),路径绑定到DataContext,但在代码后面LayoutRoot.DataContext = App.ViewModel;,因此将LayoutRoot更改为this

  • 将属性CompanyName更改为类MainViewModel中的公共属性

  • 在方法中添加sender.txtCompanyName.Text = newValue CompanyNameChanged在类MyUserControl 中。当控件启动时,数据上下文可能未初始化,因此当您设置txtCompanyName.Text = CompanyName时,公司名称为空。更改CompanyName属性时,必须重置txtCompanyName

代码:

sender.txtCompanyName.Text = newValue;

希望这能帮助你。如果帮助您,请将其标记为答案。