簡體   English   中英

將屬性綁定到UserControl

[英]Bind property to UserControl

我有與此線程相同的問題。

我也閱讀了這篇文章,但找不到導致此異常的原因:

在此處輸入圖片說明

我正在調用其中應調用另一個UserControl的UserControl。

在第一個UserControl中,我要執行以下操作

<UserControl
x:Class="TwitterUniversalHubTest1.UCGlobalTweet"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TwitterUniversalHubTest1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="150"
d:DesignWidth="400">

<Grid Height="Auto">
    <Border Background="#FFFFFFFF" Margin="10 0 0 5" CornerRadius="2 2 15 2">
        <Grid Width="380">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <StackPanel Tag="{Binding UserID}" Grid.Row="0" Name="ProfileInfo" Tapped="Profile_Tapped" Orientation="Horizontal" Margin="15 15 15 0">
                <Grid Width="360" Margin="0 0 0 10">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="75"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="50"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" Height="45" Width="45" CornerRadius="5">
                        <Border.Background>
                            <ImageBrush ImageSource="{Binding ImagePath}" Stretch="UniformToFill"/>
                        </Border.Background>
                    </Border>
                    <StackPanel Grid.Column="1" Orientation="Vertical" Margin="0 5 0 0">
                        <TextBlock Text="{Binding FullName}" Foreground="Black" FontSize="18" FontWeight="Bold"></TextBlock>
                        <TextBlock Text="{Binding TwitterHandle}" Foreground="DarkGray" FontSize="12"/>
                    </StackPanel>
                    <Image Grid.Column="2" Source="Assets/ActionIcons/Twitter_logo_blue_32.png" Width="32" VerticalAlignment="Top"></Image>
                </Grid>
            </StackPanel>

            <StackPanel  Grid.Row="1" Margin="14.5,0,0,0" Height="Auto">

                <StackPanel Name="TwContent" Tag="{Binding TweetID}" Margin="15 0 15 0" Tapped="Content_Tapped">

                    <local:ComplexTextPresenter x:Name="ComplexTextPresenterElement" Input="{Binding Content}" DataContext="{Binding Content}"/>
                    <ItemsControl  ItemsSource="{Binding ContentImages}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Image Source="{Binding }" MaxWidth="350" Margin="0 0 0 5"  HorizontalAlignment="Center"></Image>

                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                    <TextBlock Foreground="DarkGray" Text="{Binding DateSend}" FontSize="10"></TextBlock>
                </StackPanel>
                <StackPanel Name="ActionButtons">
                    <Grid Tag="{Binding TweetID}" Width="380" Height="25" Margin="0 0 0 10">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>

                        <Button Grid.Column="0" HorizontalAlignment="Center" Margin="20 0 0 0" Style="{StaticResource replyActionButton}" Tapped="Reply_Tapped"></Button>

                        <ToggleButton Grid.Column="2" HorizontalAlignment="Center" Style="{StaticResource retweetActionButton}" Tapped="Retweet_Tapped"></ToggleButton>
                        <TextBlock Grid.Column="3" HorizontalAlignment="Left" Margin="-15 0 0 0" VerticalAlignment="Center" Text="{Binding RetweetCount}" Foreground="DarkGray"/>

                        <ToggleButton x:Name="FavButton" Grid.Column="4" HorizontalAlignment="Center" 
                                          Style="{StaticResource likeActionButton}" 
                                          IsChecked="{Binding LikeState}"  
                                          Tapped="Favourite_Tapped"/>
                        <TextBlock Grid.Column="5"  HorizontalAlignment="Left" Margin="-15 0 0 0" VerticalAlignment="Center" Text="{Binding LikeCount}" Foreground="DarkGray"/>
                    </Grid>
                </StackPanel>
            </StackPanel>
        </Grid>
    </Border>
</Grid>

Input="{Binding Content}"的Content屬性是一個字符串。

輸入屬性綁定會出現問題。 ItemsControl中的綁定工作正常。 例外情況是綁定在Line:43 Position:90中。

ComplexTextPresenterElement的背后代碼如下所示:

public static readonly DependencyProperty InputProperty = DependencyProperty.Register("Input", typeof(string), typeof(UCGlobalTweet), new PropertyMetadata(default(string), InputPropertyChangedCallback));

private static void InputPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    var ctrl = dependencyObject as ComplexTextPresenter;
    if (ctrl == null)
        return;
    ctrl.Init();
}

public static readonly DependencyProperty InputCollectionProperty = DependencyProperty.Register("InputCollection", typeof(ObservableCollection<object>), typeof(UCGlobalTweet), new PropertyMetadata(default(ObservableCollection<object>)));
public static readonly DependencyProperty OnHyperlinkCommandProperty = DependencyProperty.Register("OnHyperlinkCommand", typeof(ICommand), typeof(UCGlobalTweet), new PropertyMetadata(default(ICommand)));

private IEnumerable<object> GetParsedInput()
{
    List<BaseInputPart> inputParts = new List<BaseInputPart>();
    var strings = Input.Split(new[] { " " }, StringSplitOptions.None).ToList();

    foreach (var s in strings)
    {
        if (s.IsHyperlink())
        {
            inputParts.Add(new HyperLinkPart { Content = s });
        }
        else
        {
            inputParts.Add(new LiteralPart { Content = s });
        }
    }
    return inputParts.OfType<object>().ToList();
}

public string Input
{
    get { return (string)GetValue(InputProperty); }
    set { SetValue(InputProperty, value); }
}

public ObservableCollection<object> InputCollection
{
    get { return (ObservableCollection<object>)GetValue(InputCollectionProperty); }
    private set { SetValue(InputCollectionProperty, value); }
}

public ICommand OnHyperlinkCommand
{
    get { return (ICommand)GetValue(OnHyperlinkCommandProperty); }
    set { SetValue(OnHyperlinkCommandProperty, value); }
}

private void Init()
{
    InputCollection = new ObservableCollection<object>(GetParsedInput());
}

public ComplexTextPresenter()
{
    this.InitializeComponent();
}


public abstract class BaseInputPart
{
    public abstract string Content { get; set; }
}

public class HyperLinkPart : BaseInputPart
{
    public override string Content { get; set; }
}

public class LiteralPart : BaseInputPart
{
    public override string Content { get; set; }
}

//更新:這是UCGlobalTweet.xaml.cs

    public sealed partial class UCGlobalTweet : UserControl
{
    private readonly NavigationHelper navigationHelper;
    private readonly ObservableDictionary defaultViewModel = new ObservableDictionary();
    private readonly ResourceLoader resourceLoader = ResourceLoader.GetForCurrentView("Resources");

    //passingparameter
    public string MyContentProperty { get; set; }

    public UCGlobalTweet()
    {
        this.InitializeComponent();
        Init();
    }

    private void Init()
    {

        ComplexTextPresenterElement.Input = "This is where the Content string has to be....";
        ComplexTextPresenterElement.OnHyperlinkCommand = new RelayCommand<object>(Execute);
    }

    private void Execute(object o)
    {
        //put here the code that can open browser 
    }

    public ObservableDictionary DefaultViewModel
    {
        get { return this.defaultViewModel; }
    }

    // Tap user specific content
    private void Profile_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Debug.WriteLine("I've clicked on information from Profile --> UserInfoPage");
        List<object> passingParameters = new List<object>();

        StackPanel st = (StackPanel)sender;
        string userIDList = (string)st.Tag;

        //provisional Data transfer
        // get UserObject out of SearchResult, therefore I have to put the user content as a global variable to access it here, but this will require a lot of space probably...
        // So for now I recall the UserObject again.

        var usersResponse =
               (from user in TweetContent.Connection.User
                where user.Type == UserType.Lookup &&
                      user.UserIdList == userIDList
                //user.ScreenNameList == "JoeMayo,Linq2Tweeter"
                select user).ToList();

        User curUser = usersResponse.FirstOrDefault();
        passingParameters.Add(curUser);

        (Window.Current.Content as Frame).Navigate(typeof(UserInfoPage), passingParameters);
    }

    // Tap tweet specific content
    private void Content_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Debug.WriteLine("I've clicked the Tweet content --> Going to TweetInfoPage");
        List<object> passingParameters = new List<object>();

        StackPanel ContentTapped = (StackPanel)sender;
        ulong tag = (ulong)ContentTapped.Tag;
        var test = TweetContent.FulltweetList;
        var tweet = test.FirstOrDefault(tw => tw.TweetID == tag);

        passingParameters.Add(tweet);


        (Window.Current.Content as Frame).Navigate(typeof(TweetInfoPage), passingParameters);

    }

    //Action Buttons
    private void Reply_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Debug.WriteLine("Reply Button Tapped");
        var test = (Button)sender;

        e.Handled = true;
        Debug.WriteLine("New State for Reply: " + test.IsPressed);
    }

    private void Retweet_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Debug.WriteLine("Retweet Button Tapped");
        //var test = (Button)sender;

        //e.Handled = true;
        //Debug.WriteLine("New State for Retweet: " + test.IsPressed);
    }

    private async void Favourite_Tapped(object sender, TappedRoutedEventArgs e)
    {
        try
        {
            Debug.WriteLine("Favourite Button Tapped");
            ToggleButton tBtn = (ToggleButton)sender;
            Grid pGrid = (Grid)tBtn.Parent;
            var curTweet = TweetContent.FulltweetList.Where(tw => tw.TweetID.Equals(pGrid.Tag));

            if (tBtn.IsChecked == false)
            {
                Debug.WriteLine("Status should be Checked: " + tBtn.IsChecked);
                await TweetContent.Connection.DestroyFavoriteAsync((ulong)pGrid.Tag);
                curTweet.First().LikeCount--;
            }

            if (tBtn.IsChecked == true)
            {
                Debug.WriteLine("Status should be UnChecked: " + tBtn.IsChecked);
                await TweetContent.Connection.CreateFavoriteAsync((ulong)pGrid.Tag);
                curTweet.First().LikeCount++;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error while updating Favourite State: Message: " + ex);
        }
        finally
        {
            e.Handled = true;
        }
    }

    private void RealLink_Clicked(object sender, RoutedEventArgs e)
    {
        var hyperlink = sender as Hyperlink;
        if (hyperlink == null) return;
        //Process.Start(hyperlink.NavigateUri.AbsoluteUri);
    }

}

接下來是ComplexTextPresenter.xaml-我剛才所說的第二個UserControl

<UserControl
x:Class="TwitterUniversalHubTest1.ComplexTextPresenter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ts="using:TwitterUniversalHubTest1"
xmlns:panel="using:Gregstoll"  
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400" x:Name="This">
<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="HyperlinkDataTemplateKey">
            <HyperlinkButton Padding="0" Margin="0" FontSize="12" CommandParameter="{Binding }" Command="{Binding ElementName=This, Path=OnHyperlinkCommand}" Content="{Binding Path=Content}" Foreground="Blue"/>
        </DataTemplate>
        <DataTemplate x:Key="LiteralDataTemplateKey">
            <TextBlock Padding="0" Margin="0" FontSize="12" Text="{Binding Path=Content}"></TextBlock>
        </DataTemplate>
        <ts:MyDataTemplateSelector x:Key="DataTemplateSelectorKey"
                              LiteralDataTemplate ="{StaticResource LiteralDataTemplateKey}"
                              HyperlinkDataTemplate="{StaticResource HyperlinkDataTemplateKey}"/>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <!--<Rectangle Fill="Green" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
    <ListBox Margin="-5 0 0 15" Foreground="Black" ItemsSource="{Binding ElementName=This, Path=InputCollection}" ItemTemplateSelector="{StaticResource DataTemplateSelectorKey}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <panel:UniversalWrapPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ListBox>
</Grid>

干杯,烏爾平

綁定中沒有DataContextElementNameSource 有幾種方法可以使代碼正常工作,我將為您提供最簡單的方法,您可以選擇其中的任何一種。

1)將您的UserControlDataContext設置為{Binding RelativeSource={RelativeSource Self}} 但是,這是一種不好的方法,因為您可能會覆蓋現有的DataContext或從外部代碼中覆蓋它。

2)命名您的UserControl並使用ElementName綁定到它。

Input="{Binding Content, ElementName=userControl}"

3)使用{x:Bind}

Input="{x:Bind Content}"

注冊屬性時,應傳遞包含屬性的類的類型,但應傳遞typeof(UCGlobalTweet) 您應該這樣做:

class ComplexTextPresenterElement
{
    public static readonly DependencyProperty InputProperty = DependencyProperty.Register("Input", typeof(string), typeof(ComplexTextPresenterElement), new PropertyMetadata(default(string), InputPropertyChangedCallback));    
    public static readonly DependencyProperty InputCollectionProperty = DependencyProperty.Register("InputCollection", typeof(ObservableCollection<object>), typeof(ComplexTextPresenterElement), new PropertyMetadata(default(ObservableCollection<object>)));
    public static readonly DependencyProperty OnHyperlinkCommandProperty = DependencyProperty.Register("OnHyperlinkCommand", typeof(ICommand), typeof(ComplexTextPresenterElement), new PropertyMetadata(default(ICommand)));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM