Binding Properties not updating (1 Viewer)

sccrgoalie1

Portal Pro
September 12, 2013
109
165
34
United States of America United States of America
Hello,

I'm slowly learning the new MP2 development and I'm having an issue with Binding that I can figure out. I know my model is bound correctly because when I set the property on first load it works just fine. The problem is when I try to update that property later nothing happens. Here's the relevant code:

XAML
XML:
 <Grid x:Name="Picture1Grid" Margin="{Binding Path=Picture1GridMargin}">
        <Grid.RenderTransform>
            <TransformGroup>
                            <RotateTransform CenterX="100" CenterY="75" Angle="0" />
                            <ScaleTransform ScaleX="1" ScaleY="1"/>
                        </TransformGroup>
        </Grid.RenderTransform>
            <Border x:Name="Picture1Border" BorderBrush="White"
                    BorderThickness="10" MaxWidth="{Binding Path=Picture1Width}"
                    MaxHeight="{Binding Path=Picture1Height}"
                    HorizontalAlignment="Left" VerticalAlignment="Top" >
            <Image Source ="{Binding Path=Picture1}" Stretch="Uniform"/>
        </Border>
        <Label x:Name="Picture1Label" Content="{Binding Path=Picture1Date}"
              HorizontalAlignment="Center" VerticalAlignment="Bottom"
              Color="{Binding Path=Picture1DateColor}" FontSize="8"/>
    </Grid>
CS
C#:
protected readonly AbstractProperty _picture1Property;
    protected readonly AbstractProperty _picture1GridMargin;
    protected readonly AbstractProperty _picture1Date;
    protected readonly AbstractProperty _picture1DateColor;
    protected readonly AbstractProperty _picture1Width;
    protected readonly AbstractProperty _picture1Height;

public MPPhotoSlideshowModel()
    {
      try
      {
        // In models, properties will always be WProperty instances. When using SProperties for screen databinding,
        // the system might run into memory leaks.
        log = new Log(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\Team MediaPortal\MP2-Client\Log", "MPPhotoSlideshow", "log", LogType.Debug);
        _helloStringProperty = new WProperty(typeof(string), HELLOWORLD_RESOURCE);
        _picture1Property = new WProperty(typeof(object), null);
        _picture1Date = new WProperty(typeof(string), null);
        _picture1GridMargin = new WProperty(typeof(object), null);
        _picture1DateColor = new WProperty(typeof(object), null);
        _picture1Width = new WProperty(typeof(object), null);
        _picture1Height = new WProperty(typeof(object), null);
        LoadSettings();
        LoadPage();
      }
      catch (Exception ex)
      {
        if (log != null)
        {
          log.writeLog(ex.ToString(), LogInfoType.Error);
        }
      }
    }

public string Picture1Date
    {
      get { return (string)_picture1Date.GetValue(); }
      set { _picture1Date.SetValue(value); }
    }
    public object Picture1
    {
      get { return (object)_picture1Property.GetValue(); }
      set { _picture1Property.SetValue(value); }
    }
    public object Picture1GridMargin
    {
      get { return (object)_picture1GridMargin.GetValue(); }
      set { _picture1GridMargin.SetValue(value); }
    }
    public object Picture1DateColor
    {
      get { return (object)_picture1DateColor.GetValue(); }
      set { _picture1DateColor.SetValue(value); }
    }
    public object Picture1Height
    {
      get { return (object)_picture1Height.GetValue(); }
      set { _picture1Height.SetValue(value); }
    }
    public object Picture1Width
    {
      get { return (object)_picture1Width.GetValue(); }
      set { _picture1Width.SetValue(value); }
    }
private void LoadPage()
    {
      try
      {
        PhotoTemplate template = _photoTemplates[_templateRnd.Next(_photoTemplates.Count)];
        if (template.Photos[0].Enabled)
        {
          Picture picture1FileName;
          if (template.Photos[0].Image.Height > template.Photos[0].Image.Width)
          {
            picture1FileName = _verticalPictures[_verticalRnd.Next(_verticalPictures.Count)];
          }
          else
          {
            picture1FileName = _horizontalPictures[_horizontalRnd.Next(_horizontalPictures.Count)];
          }
          //log.writeLog(String.Format("MPSlideshow.LoadPage() - Setting new file name {0}",picture1FileName.FilePath), LogInfoType.Debug);
          Picture1 = picture1FileName.FilePath;
          Picture1GridMargin = String.Format("{0},{1},{2},{3}", template.Photos[0].Image.posX, template.Photos[0].Image.posY, 0, 0);
          Picture1Date = picture1FileName.DateTaken.ToString("d");
          Picture1DateColor = template.Photos[0].Label.TextColor;
          Picture1Width = template.Photos[0].Image.Width;
          Picture1Height = template.Photos[0].Image.Height;
        }
      }
      catch (Exception ex)
      {
        log.writeLog(ex.ToString(), LogInfoType.Error);
      }
    }
Any idea why this isn't updating. The LoadPage() method is called every 10 seconds via a timer tick event.
 
Last edited by a moderator:

Holzi

Super Moderator
  • Team MediaPortal
  • April 21, 2010
    7,930
    2,234
    Ba-Wü
    Germany Germany
    Country flag
    It is always nice to have people which are interested in MP2. Hopefully some MP2 dev can help you.
    Thanks! :)
     

    BigGranu

    Development Group
  • Team MediaPortal
  • February 7, 2013
    238
    172
    49
    Germany Germany
    Country flag
    XML:
    <Label x:Name="Picture1Label" Content="{Binding Path=Picture1Date}"
                  HorizontalAlignment="Center" VerticalAlignment="Bottom"
                  Color="{Binding Path=Picture1DateColor}" FontSize="8"/>
    Use "Mode=TwoWay"

    XML:
    <Label x:Name="Picture1Label" Content="{Binding Path=Picture1Date, Mode=TwoWay}"
                  HorizontalAlignment="Center" VerticalAlignment="Bottom"
                  Color="{Binding Path=Picture1DateColor}" FontSize="8"/>
    I, hope it works.
     
    Last edited by a moderator:

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,397
    6,966
    Germany Germany
    Country flag
    The cause is simple, I had to learn this difference to WPF myself:
    In MPF you also need to expose the AbstractProperty for xaml binding.

    If your property is named "Width" you have to expose "public AbstractProperty WidthProperty".

    Another important note: from models use only WProperty (weak references). SProperty is only allowed for controls.

    For an example and comments take look at the HelloWorldModel:
    C#:
        /// <summary>
        /// This sample property will be accessed by the hello_world screen. Note that the data type must be the same
        /// as given in the instantiation of our backing property <see cref="_helloStringProperty"/>.
        /// </summary>
        public string HelloString
        {
          get { return (string) _helloStringProperty.GetValue(); }
          set { _helloStringProperty.SetValue(value); }
        }
    
        /// <summary>
        /// This is the dependency property for our sample string. It is needed to propagate changes to the skin.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If the screen databinds to the <see cref="HelloString"/> property in a binding mode which will propagate data
        /// changes from the model to the skin (OneWay, TwoWay), the SkinEngine will attach a change handler to this property
        /// and react to changes.
        /// </para>
        /// <para>
        /// In other words: For each property <c>Xyz</c>, which should be able to be attached to, there must be an
        /// <see cref="AbstractProperty"/> with name <c>XyzProperty</c>.
        /// Only if <c>XyzProperty</c> is present in the model, value changes can be propagated to the skin.
        /// </para>
        /// </remarks>
        public AbstractProperty HelloStringProperty
        {
          get { return _helloStringProperty; }
        }
     
    Last edited:

    sccrgoalie1

    Portal Pro
    September 12, 2013
    109
    165
    34
    United States of America United States of America
    Thank you!! I can't believe I missed that. I've been using hello world as my base template. I made the change and now it's working properly!
     

    sccrgoalie1

    Portal Pro
    September 12, 2013
    109
    165
    34
    United States of America United States of America
    Some more binding issues, I'm attempting to improve my plugin by using an ItemsControl instead of explicitly adding each item in XAML. I've tested the code below in Blend and it works, so I'm pretty sure my binding is the issue. I've been trying to get this working for about a week, so any help would be appreciated. I've been trying use the weather model as my source. Also, I did add the ObservableCollection to MP2 as shown in this branch https://github.com/MediaPortal/MediaPortal-2/tree/FEAT_ObservableCollections

    Here's the code:

    xaml
    Code:
    <Screen xmlns="www.team-mediaportal.com/2008/mpf/directx"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Context="{Model Id=C6B0FA5A-288E-405A-A5D5-AA66CC0AA327}">
        <Screen.Resources>
            <Model x:Key="Model" Id="C6B0FA5A-288E-405A-A5D5-AA66CC0AA327"/>
        </Screen.Resources>
        <Canvas DataContext="{Binding Source={StaticResource Model}}">
            <Canvas.Background>
                <ImageBrush ImageSource="{Binding Path=SlideshowBackgroundProperty}" Stretch="Fill"/>
            </Canvas.Background>
            <HeaderedItemsControl ItemsSource="{Binding Path=PictureList}">
                <HeaderedItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas Background="Green"/>
                    </ItemsPanelTemplate>
                </HeaderedItemsControl.ItemsPanel>
                <HeaderedItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding Path=Left}"/>
                        <Setter Property="Canvas.Top" Value="{Binding Path=Top}"/>
                    </Style>
                </HeaderedItemsControl.ItemContainerStyle>
                <HeaderedItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Image Source ="{Binding Path=PictureImage}" Stretch="Uniform" MaxWidth="50" MaxHeight="50"/>
                    </DataTemplate>
                </HeaderedItemsControl.ItemTemplate>
            </HeaderedItemsControl>       
        </Canvas>
    </Screen>
    Binding Picture
    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    
    namespace MPPhotoSlideshow
    {
      public class BindingPicture:INotifyPropertyChanged
      {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
          if (PropertyChanged != null)
          {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
        }
        private int _left;
        public int Left
        {
          get { return _left; }
          set
          {
            if (_left != value)
              _left = value;
            NotifyPropertyChanged("Left");
          }
        }
        private int _top;
        public int Top
        {
          get { return _top; }
          set
          {
            if (_top != value)
              _top = value;
            NotifyPropertyChanged("Top");
          }
        }
        private string _pictureImage;
        public string PictureImage
        {
          get { return _pictureImage; }
          set
          {
            if (_pictureImage != value)
              _pictureImage = value;
            NotifyPropertyChanged("PictureImage");
          }
        }
    }
    Model

    Code:
    protected readonly AbstractProperty _slideshowBackgroundProperty;
    private ObservableCollection<BindingPicture> _pictureList = null;
    public ObservableCollection<BindingPicture> PictureList;
    public string SlideshowBackground
        {
          get { return (string)_slideshowBackgroundProperty.GetValue(); }
          set { _slideshowBackgroundProperty.SetValue(value); }
        }
    public AbstractProperty SlideshowBackgroundProperty
        {
          get { return _slideshowBackgroundProperty; }
        }
    public MPPhotoSlideshowModel()
        {
          try
          {
    _slideshowBackgroundProperty = new WProperty(typeof(object), null);
    settings = new XMLSettings(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\MPPhotoSlideshow\", "MPPhotoSlideshow2.xml");
            SlideshowBackground= settings.getXmlAttribute("BackgroundPath");
            _pictureList= new ObservableCollection<BindingPicture>();
            _pictureList.Add(new BindingPicture() { Left=10, Top=10, PictureImage=@"C:\Users\Mark\Pictures\Tulips.jpg"});
            PictureList.FireChange();
    }
    }
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,397
    6,966
    Germany Germany
    Country flag
    I created the ObservableCollection recently, but after doing so, I think it's not the best idea to use them. The problem is that it fires change notification after each change (add, remove), which is slow. So I hesitate to merge this branch, as it is not an optimal solution for MPF.

    Please use the ItemsList, its the MPF way for list bindings. Don't forget to call "ItemsList.FireChanged" once, after list has been rebuilt completely.

    Another thing: we are unfortunately missing the HeaderedItemsControl in MPF, so you might look for alternatives.

    I could use such a control also in other places, it would help a lot (i.e. TV guide) :(
     

    sccrgoalie1

    Portal Pro
    September 12, 2013
    109
    165
    34
    United States of America United States of America
    I created the ObservableCollection recently, but after doing so, I think it's not the best idea to use them. The problem is that it fires change notification after each change (add, remove), which is slow. So I hesitate to merge this branch, as it is not an optimal solution for MPF.

    Please use the ItemsList, its the MPF way for list bindings. Don't forget to call "ItemsList.FireChanged" once, after list has been rebuilt completely.
    Alright, I'll switch it up to an ItemList. Thanks.

    Another thing: we are unfortunately missing the HeaderedItemsControl in MPF, so you might look for alternatives.

    I could use such a control also in other places, it would help a lot (i.e. TV guide) :(
    I originally tried using an ItemsControl but that didn't exist in MPF, HeaderedItemsControl does seem to exist at least partially. It may not be fully implemented and that's a reason it's not working, but it is in the source.
     

    morpheus_xx

    Lead Dev MP2
  • Team MediaPortal
  • March 24, 2007
    11,397
    6,966
    Germany Germany
    Country flag
    HeaderedItemsControl does seem to exist at least partially. It may not be fully implemented and that's a reason it's not working, but it is in the source
    Oh, yes you are right. It is used for TreeView and TreeViewItem, so it should also work :)
     

    Users Who Are Viewing This Thread (Users: 0, Guests: 1)

    OP Similar threads Forum Replies Date
    B [Finished] [MP2-817] Implement NotifyOnSourceUpdated and NotifyOnTargetUpdated binding events MediaPortal 2 3
    Rob Hexenmeister Mediaportal Properties #plot etc... General Support 3
    Rob Hexenmeister Latest Media Handler - facade properties - itemcount General Support 3
    ajs [solved] New property in VideoArtistInfo page MediaPortal 1 24
    zunixnuz Missing #iswatched property to recorded TV Titan Skin Feedback 5
    G Update von MediaPortal Installationsprobleme? 0
    morpheus_xx [Evaluate] Update to VS 2019? MediaPortal 2 4
    Golf4 Nach Windows-Updates läuft TV-Plugin nicht mehr Allgemeines Support- und Diskussionsforum 0
    B MPEM update list never completes. General Support 0
    JJDoherty Updated DTT frequencies for Ireland... Submit: EPG-Grabbers and tuningdetails 1
    Dark Eyes Updated to Windows 10, now TVServer won't work Installation, configuration support 1
    R [solved] Files moved to new location - Easy way to update database? My TVSeries 7
    M.Hulot Moving Pictures lässt sich nach Windows-Update nicht mehr öffnen Plugins & Erweiterungen 1
    R Files moved to different location - Easy way to update database? Moving Pictures 2
    k12158 [solved] Kein direkter Wechsel von TV-Kanal zu TV-Kanal mehr nach Update? Allgemeines Support- und Diskussionsforum 16
    ajs Mediaportal update to .Net 4.6.2+ MediaPortal 1 13
    Mr6686 [solved] Titan skin broken since update to 1.23 Installation, configuration support 6
    B TV-Server Auto-Update mptvdb after x hours General Support 0
    Terra LAVFilter Plugin cannot be updated (MP1.23) MediaPortal 1 Plugins 10
    TLD Windows 10 1903 feature update General Support 3
    azzuro [Pending] Update MP1 to VisualStudio 2019 MediaPortal 1 36
    A Problem Windows 10 64 bit prof. Update auf Version 1903(gelöst) Installationsprobleme? 0
    T No TV after updating Windows 10 to latest Version 1903 / OS build 18362.175 (logs attached) General Support 2
    M [solved] Updated Swedish translation for MP 1.24 Submit: Localization of MediaPortal and DeployTool 0
    framug 1.22.0 BasicHome Editor settings for DefaultWide HD skin not kept when update 1.22 3
    Similar threads

























    Top Bottom