简体   繁体   中英

Binding to a custom XAML control property won't work

I'm trying to create a Windows 10 UWP application with C# and XAML. At this point I'm quite stuck with data binding in item templates.

So basically, I have a ViewModel, that is bound to the XAML controls.

I want to bind the data model to a property of a custom control. The thing is that some things work, some don't and I can't really understand why.

So this binding works:

  <GridView   ItemsSource="{Binding MediaElementId}" >
       <GridView.ItemTemplate>
           <DataTemplate>
               <TextBlock Text="{Binding}" />
           </DataTemplate>
        </GridView.ItemTemplate>
   </GridView>

But when i put other things insted of the TextBlock, it won't work.

For example these bindings won't work :

<TextBlock  Text="{Binding  Path=.}"/>
 <controls:CustomControl Test="{Binding Path=., UpdateSourceTrigger=PropertyChanged}"  />
 <controls:CustomControl Test="{Binding Path=., RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
 <controls:CustomControl Test="{Binding}"/>

So, I basically found documentation, that {Binding} is equivalent with {Binding Path=.}, but in this example it doesn't really seem that way.

You can try it yourself in a project, where I isolated the issue: https://bitbucket.org/MrGreeny/pivottestapp/src/4edee74acfac6dbb4f9f042acaf389cc6fd90a31?at=master

Edit: The property is a pretty simple one:

    private string test;

    public string Test
    {
        get { return null; }
        set
        {
            Debug.WriteLine(value);
           //What i think should be here is for example textblock.Text = value
        }
    }

So, basically all I had to do was use DependencyProperty instead of a normal property. Here is the working solution:

First the control inside the DataTemplate :

<GridView ItemsSource="{Binding MediaElementId}" >
   <GridView.ItemTemplate>
      <DataTemplate>
         <local:CustomControl TextBlockContent="{Binding}" />
      </DataTemplate>
   </GridView.ItemTemplate>
 </GridView>

Then in the custom control xaml.cs file:

First is the wrapper exposing the DependencyProperty :

public string TextBlockContentProperty
{
    get { return (string)GetValue(TextBlockContentPropertyProperty); }
    set { SetValue(TextBlockContentPropertyProperty, value); }
}

Then the DependencyProperty itself.

     public static readonly DependencyProperty TextBlockContentPropertyProperty =
        DependencyProperty.Register(
           "TextBlockContentProperty", 
           typeof(string), 
           typeof(CustomControl), 
           new PropertyMetadata(0, new PropertyChangedCallback(OnTextChanged)) );

Note, that the last argument contains the connection to the OnTextChanged function, wherewe have access to the object instance. All of the above are static , and we can't use them to change the instance of the object.

Here is how I implemented the instance specific logic. TextBlockContent is the normal property, that exposes the Text property of a TextBlock , that is the content of the custom control.

    private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CustomControl cc = d as CustomControl;
        string content = (string)e.NewValue;
        cc.TextBlockContent = content;
    }

Thanks to everyone, who answered my original question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM