将datacontext绑定到usercontrol

时间:2014-03-29 10:08:59

标签: c# wpf xaml windows-phone-8 windows-phone

我创建了我的UserControl,在后面的代码中我添加了属性CompanyName,FirstName和SecondName。我为每个属性添加了DependencyProperty。在xaml中我使用LongListSelector,我想在ItemTemplate中绑定一些来自viewmodel的东西:observable collection(FirstName和SecondName)和一个字符串(CompanyName)。

由于某种原因,未触发CompanyName的DependencyProperty,并且该值未绑定。对于ObservableCollection,一切都是绑定的。

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

我将给我的一半王国和我的女儿解决这个问题,因为我将面临这个问题几天。

Here is the example solution

这是代码..

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>

1 个答案:

答案 0 :(得分:1)

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

  • 页面CompanyName="{Binding ElementName=self, Path=DataContext.CompanyName}"中的代码MainPage,您将CompanyName绑定到self(页面),DataContext的路径,但在{{1}后面的代码中},所以将LayoutRoot.DataContext = App.ViewModel;更改为LayoutRoot

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

  • 在班级MainViewModel的方法sender.txtCompanyName.Text = newValue中添加CompanyNameChanged。当控件处于初始化状态时,DataContext可能未初始化,因此当您设置MyUserControl时,CompanyName为null。 txtCompanyName.Text = CompanyName属性更改后,您必须重置txtCompanyName

代码:

CompanyName

希望这可以帮到你。如果有帮助,请将其标记为答案。