0

Trying to understand this better.

I have an ItemsControl defined in my mainview something like this

<ItemsControl  Grid.Column="0" Grid.Row="2"
                   ItemsSource="{Binding Notes}" 
                   ItemTemplate="{Binding Source={StaticResource MyParagraph}}"
  >

</ItemsControl> 

in which I would like to use a DataTemplate:

<UserControl.Resources>
    <DataTemplate x:Key="MyParagraph">
        <v:InkRichTextView
            RichText="{Binding ?????? "
     </DataTemplate>
</UserControl.Resources>

The InkRichTextView is a view with a dependency property, RichText, being used to pass a paragraph from the ObservableCollection(InkRichViewModel) Notes in the mainview to the user control. That is, this works correctly for one paragragh:

<v:InkRichTextView RichText ="{Binding Path=Note}" Grid.Column="0" Grid.Row="0" />

where Note is defined as a paragraph in the MainView.

The problem is, how do I write the DataTemplate and the ItemsControl such that the ItemsControl can pass each paragraph from the observablecollection to the dependency property RichText in the InkRichTextView?

Thanks for any guidance. (I hope this is understandable!)

5
  • How is the InkRichViewModel declared? Does it have a property called "Note"? Commented Dec 6, 2014 at 21:33
  • @Murven RichText is a dependency property in my user control InkRichTextView. I have so far been unable to use a different DataContext for the user control without losing the dependency property. I would sure like to though. (I will be happy with anyway this can be made to work!) Commented Dec 6, 2014 at 21:43
  • @Murven The dependency property is defined in the code-behind of InkRichTextView. Commented Dec 6, 2014 at 21:44
  • 1
    It is fine for RichText to be a dependency property, that is the appropriate design because it is in a control. I mean the structure of the class InkRichViewModel and whether this view model class has a property called Note and whether this property is raising the PropertyChanged event. Commented Dec 6, 2014 at 21:46
  • @Murven InkRickViewModel implements INotifyPropertyChanged, but I could never get how to make the UserControl use its own DataContext without loosing the dependency property in its code-behind. At this point, InkRichViewModel does not have a Note property and I do not know how to have the ItemsControl read paragraphs from the MainView and still have a separate DataContext? Help please! Commented Dec 6, 2014 at 22:03

3 Answers 3

1

Items control:

    <ItemsControl x:Name="NotesItemsControl" Grid.Column="2" HorizontalAlignment="Center">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <local:InkRichTextView RichText="{Binding Note}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Code behind:

    class InkRichViewModel : System.ComponentModel.INotifyPropertyChanged
    {
        #region Note (INotifyPropertyChanged Property)
        private string _note;

        public string Note
        {
            get { return _note; }
            set
            {
                if (_note != value)
                {
                    _note = value;
                    RaisePropertyChanged("Note");
                }
            }
        }
        #endregion

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string p)
        {
            var propertyChanged = PropertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(p));
            }
        }
    }


    public MainWindow()
    {
        InitializeComponent();

        var item01 = new InkRichViewModel() { Note = "Note 01", };
        var item02 = new InkRichViewModel() { Note = "Note 02", };
        var item03 = new InkRichViewModel() { Note = "Note 03", };
        var item04 = new InkRichViewModel() { Note = "Note 04", };
        var item05 = new InkRichViewModel() { Note = "Note 05", };
        var itemList = new List<InkRichViewModel>() 
        {
            item01, item02, item03, item04, item05,
        };
        NotesItemsControl.ItemsSource = itemList;

    }

How it looks at runtime:

How it looks at runtime

Is that what you're looking for?

Sign up to request clarification or add additional context in comments.

1 Comment

Yes! Now if I could figure out how to move the DataTemplate back into the Resources, everything would be perfect. Thank you.
1

Based on what you describe, it seems that each item in your ItemsControl is a paragraph, the very object you want to assign to the InkRichTextView.RichText property. Is that correct?

If so, keep in mind that within the item template, the data context is the collection item itself - thus, the path you are looking for does not refer to a property of the data context, but to the data context itself.

That is done with the dot (.) path:

<v:InkRichTextView RichText="{Binding .}"/>

3 Comments

The above is helpful, but now I get 10 blank paragraphs displayed. As far as I can tell, the RichText is not being initialized. ???
@AlanWayne: Are there any binding errors displayed by your IDE?
Yep. as seen in the Output window, Value produced by BindingExpression is not valid for target property.; Value='Nova5.UI.ViewModels.Ink.InkRichViewModel' BindingExpression:Path=.; DataItem='InkRichViewModel' (HashCode=16892667); target element is 'InkRichTextView' (Name=''); target property is 'RichText' (type 'Paragraph')
0

I'm posting this as an answer, although the credit goes to O.R.Mapper and Murven for pointing me in the right direction. My post is to help anyone else just learning this.

In very simple terms, the ItemControl performs a looping action over the collection in its ItemsSource. In my case the ItemsSource is a collection of type InkRichViewModel. (Hence the question from Murven). In its looping action, the ItemsSource will create objects from the InkRichViewModel. (Thus, my usercontrol now has an individual datacontext!) Each of these objects will use the ItemTemplate for display. So to simplify things, I moved the DataTemplate from the UserControl Resources to within the ItemControl itself as:

  <ItemsControl  Grid.Column="0" Grid.Row="2"
                   ItemsSource="{Binding Notes}" 
                   >
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <v:InkRichTextView RichText="{Binding Note}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Now that each of my usercontrols has its own datacontext being assigned by the ItemsControl, the Output window (VS2010) now shows the binding errors. Fixing these errors leads to a working solution.

Hope this helps other newbies like myself. Thanks everyone.

(Ooops! Just saw the answer from Murven but I'll leave this if it helps somebody to understand.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.