tags:

views:

26

answers:

1

Edit 2 Ok, here is the full example:

public class FixedSizeLibraryViewModel : ViewModel
{
    RawFixedLibrary _library;

    public FixedSizeLibraryViewModel(RawFixedLibrary thisLibrary)
    {
        _library = thisLibrary;
    }

    public string BookOneTitle
    {
        get { return _library.BookOne.Title; }
        set { _library.BookThree.Title = value;
            this.OnPropertyChanged("BookOneTitle");}
    }

    public string BookTwoTitle
    {
        get { return _library.BookThree.Title; }
        set { _library.BookOne.Title = value;
        this.OnPropertyChanged("BookTwoTitle");}
    }

    public string BookThreeTitle
    {
        get { return _library.BookThree.Title; }
        set { _library.BookThree.Title = value;
        this.OnPropertyChanged("BookThreeTitle");}
    }

    public string BookOneText
    {
        get { return _library.BookOne.Text; }
        set { _library.BookThree.Text = value;
        this.OnPropertyChanged("BookOneText");}
    }

    public string BookTwoText
    {
        get { return _library.BookThree.Text; }
        set { _library.BookOne.Text = value;
        this.OnPropertyChanged("BookTwoText");}
    }

    public string BookThreeText
    {
        get { return _library.BookThree.Text; }
        set { _library.BookThree.Text = value;
        this.OnPropertyChanged("BookThreeText");}
    }

    public ????? BookList{
        get{
            if(someCondition)
                //Return Book 1 and book 2 title and text in some sort of list
            else
                //Return Book 2 and book 3 title and text in some sort of list
        }
    }
}

And binding pretty much exactly as before:

    <TabControl ItemsSource="{Binding BookList}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding BookTitle}"/>
            </DataTemplate> 
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <TextBox Text="{Binding BookContents, Mode=TwoWay}"/>
            </DataTemplate> 
        </TabControl.ContentTemplate>
    </TabControl>

In the full implementation, the book titles and texts are actually very secondary to the rest of the functions of the FixedSizeLibraryViewModel. So the work around I implemented was to simply add one tab for each book, bind the header to the book title and bind the text to the book text, then conditionally hide the tabs based on an additional public property.

This is problematic if we ever need to change the books for obvious reasons. I can bind individually to BookNTitle and BookNText just fine. Changes made to those show up in the original RawFixedLibrary that was passed in. But I can't find a way to add them to a list and have changes made to them still affect the original RawFixedLibrary.

And ViewModel implments the requirements for the OnPropertyChanged calls.

End edit 2

Edit Sorry, in reality my situation is a little more complicated than I first let on. So, in reality the class looks more like this:

    private rawBookData _thisBook;

    public Book(rawBookData rawBook)
    {
        _thisBook = rawBook
        BookTitle = _thisBook.Title;
        BookText = _thisBook.Text;
    }

    public string BookTitle
    {
        get { return _thisBook.Title; }
        set { _thisBook.Title = value; }
    }

    public string BookContent
    {
        get { return _thisBook.Text; }
        set { _thisBook.Text = value; }
    }

EndEdit

I think I have been behind the monitor too long today, I feel like this is really simple and I just cant figure it out.

I have a class with some properties, namely a book title and book contents:

public class Book
{
    private string _boookTitle;
    private string _bookContent;

    public Book(string title, string content)
    {
        _boookTitle = title;
        _bookContent = content;
    }

    public string BookTitle
    {
        get { return _boookTitle; }
        set { _boookTitle = value; }
    }

    public string BookContent
    {
        get { return _bookContent; }
        set { _bookContent = value; }
    }

    public ?????? GetStrings()
    {
        ?????? stringPair;
        //I want this to return the BookTitle and BookContent as some sort of pair
        return stringPair;
    }
}

I need this GetStrings function to pass out something that I can bind to such that I can access and set the BookTitle and BookContents via binding.

I need to ultimately make a list of these objects so I can have a tab per book in a tab control. The idea being that each tab will have the book title, then you can modify the text of the book from within that tab.

I would really like to be able to just pass a list of Books, but due to some other constraints thats not really an easy option here.

So I will have something along the lines of:

    <TabControl ItemsSource="{Binding BookList}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding BookTitle}"/>
            </DataTemplate> 
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <TextBox Text="{Binding BookContents, Mode=TwoWay}"/>
            </DataTemplate> 
        </TabControl.ContentTemplate>
    </TabControl>
A: 

Why not just create a class to hold them:

public BookStuff
{
     public string BookContents {get; set;}
     public string BookTitle {get; set;}
}

Then, in your book class

public BookStuff MyBookStuff {get; set;}

If you need a collection to bind to, I would suggest an ObservableCollection:

public ObservableCollection<BookStuff> MyListOfBooks {get; set;}

then, set your ItemsSource to MyListOfBooks, and in your ItemTemplate just bind to BookTitle and BookContents

<TextBox Text="{Binding BookTitle}" ... />
Robaticus
You've just added a class to his hierarchy to hold properties that already exists in his `Book` class. His `Book` class already has the properties that he wants, so creating a `BookStuff` to do the same thing seems redundant.
Dave White
I just tried this, and the problem is, when I make a new bookstuff and set its contents and title, it works fine, then I can update the contents and title, but that doesnt translate back into editing the original _thisBook.Title or contents, and thats really the trick. I need to update those so that I can keep track of the changes to the raw data. I think your solution would have worked for my original framing of the problem, but turns out that wasnt my real problem. oops. :\
Justin
@dave : That's a good point. I would remove the properties out of the main class. @Justin : make sure it is two-way binding. Also, your BookStuff class would need to implement INotifyPropertyChanged if you want the client to be updated when things change in the model. The ObservableCollection only updates the model when items are added to / removed from the list, not when the insides of them change.
Robaticus
So the problem I face, is that I save based on the data in _thisBook.Text or _bookContent depending on which example you are looking at. So when Bookstuff.BookContents gets updated, I need to make sure, at some point, before I save, that the original source is updated to match and that is what I am having trouble with. After the initial loading nothing goes from the model to the view, so I dont need to worry about the INotifyPropertyChanged here, but I do still need to have the view put that data back into _bookContent or _rawBook.Text before it is saved back to the database.
Justin
Ok, I'm a little confused. Your binding shows the ItemsSource as BookList. What type is BookList? It looks like it should be a collection of Book. Where is BookList instantiated? Can you post some more code (particularly where you create the BookList instance, and where you assign DataContext to your window.
Robaticus
Alright, got it posted. Whats going on here is the rawlibrary is pulled from a database with NHibernate and it is a beast. It has about 25 columns. 15 of those columns are Book1, Book2 .... Book15 and the entries in those columns are the book text. But, depending on the type of rawlibrary, I only want to show a subset of those books in my tab control.
Justin
Yuck. I think what you're going to wind up having to do is marshal the changes manually between what is bound to the viewmodel, and what is bound to the _library. The other option is to bind them directly, but put all of them on the form, but manage the visibility of the controls with a property on your viewmodel. But, realistically a flat list like this is going to cause problems no matter what language you use.
Robaticus
I was worried it would come to that. I wish I got to design the database... Some of the decisions made before me really do leave me scratching my head. Thanks for the help.
Justin