2016-04-13 12 views
1

私はこのThreadと同じ問題があります。UserControlにバインドするプロパティ

私はまた、このarticleを読んだが、私はこの例外を取得してきた理由を見つけることができません。

enter image description here

私は別のユーザーコントロールが呼び出されるべきでユーザーコントロールを呼び出していますが。私はInput="{Binding Content}"

<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> 

Contentプロパティ次の操作を行うことになるでしょう最初のユーザーコントロール内

は文字列です。

問題は、Inputプロパティのバインディングで発生します。 ItemsControlのバインドは正常に動作します。例外は、バインディングを記述としてラインである:43ポジション:

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; } 
} 

// UPDATE::これはUCGlobalTweet.xaml.cs

ある90

コードビハインドComplexTextPresenterElementためには、このようになります。

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 
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> 
で話していた第二のUserControlの

乾杯、 Ulpin

+0

バインディングの 'DataContext'とは何ですか? –

+0

私は 'DataContext'に値を入れていません – Ulpin

+0

バインディングを行うために' DataContext'にある値がなければなりません。代わりに明示的に 'Source'または' ElementName'を指摘する必要があります。 –

答えて

1

はあなたがプロパティを含むクラスの型を渡す必要がありますが、あなたの代わりにtypeof(UCGlobalTweet)を渡している:

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

3){x:Bind}を使用してください。

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))); 
} 
+0

ありがとうございます。これは機能しているようです。私はこれらの3行のコードを時間の掛けすぎで演奏しており、それを理解することはできませんでした。しかし、依然として拘束力は正しくありません。 もうエラーは表示されませんが、コンテンツは表示されず、 'Windows.UI.Xaml.Controls.Grid'があります。これについて何か考えていますか? – Ulpin

+0

UCGlobalTweet userControlのコードビハインドでは、バインディングからContent文字列を準備するための計算を行っています。 ComplexTextPresenterElementインスタンスがこの時点で初期化されていないため、Init()関数に何か問題があると思います。var test = [...]で何かを試した理由です。 – Ulpin

+0

@Ulpin申し訳ありませんが、完全なソースコード。 –

1

あなたのバインディングにはDataContextElementNameSourceはありません。コードを動作させるにはいくつかのアプローチがありますが、私はあなたに最も簡単なものを与えます。これらのうちのどれかを選ぶことができます。

1)UserControlDataContext{Binding RelativeSource={RelativeSource Self}}に設定します。しかし、それは既存のDataContextを上書きするか、外部コードから上書きする可能性があるため、悪いアプローチです。

2)UserControlと名前を付けて、ElementNameを使用してバインドします。あなたがあなたの特性を登録すると

Input="{x:Bind Content}" 
+0

に変更しました。私はそれを試みます。 しかし、なぜ他のバインディングがUserControlで機能していますか?別のUserControlへのバインディングを使用する違いは何ですか? – Ulpin

+0

@Ulpin 'DataTemplate'のすべてのコントロールは、' DataContext'を現在の項目に暗黙的に設定しています。さらに、 'UserControl'は' UserControl'のように外部コードから 'DataContext'を設定することができます。 –

+0

@Ulpin '{x:Bind}'を使うことをお勧めします。私は答えを更新しました、それを見てください。 –

関連する問題