0

How would I make an XAML layout which had bound properties and events? I'm going out of my mind.

First of all, it's for a chat application and a single room chat works fine, in the sense that I can design the layout of the application in XAML with name properties here there and everywhere in order to control it in C# but when it comes to repeating this layout multiple times because of multiple rooms, it becomes a bit of a problem. I was doing it solely by C# this lead to hundreds of lines of just defining controls and adding them to the window, and one problem with that would be the fact that name properties would collide.

I was going to go with modifying a ControlTemplate of a random control for example a Frame, but then I run into the issue of defining custom properties and events.

I just have no idea how I can do what I want to do. I've asked for help in many places to no avail.

I am honestly going out of my mind, and on the verge of giving up entirely.

My aim is to have a tabcontrol with multiple rooms, I need to be able to access controls in each room with ease so I can modify the content. I'm just getting no where.

Edit

Public chat template is obviously different to the private chat template, hence why I've failed so badly at this.

  • Seems like you need an [**ItemsControl**](http://drwpf.com/blog/itemscontrol-a-to-z/) – Federico Berasategui Mar 19 '14 at 22:07
  • 2
    BTW, your frustration probably comes from trying to use WPF in a way it's not intended, I suggest you read Rachel's [**WPF Mentality**](http://stackoverflow.com/a/15684569/643085). – Federico Berasategui Mar 19 '14 at 22:08
  • I only switched to WPF on the basis that you have much more flexibility over how things look. Also, I don't really think an ItemsControl is what I'm after... I looked into DataTemplates with the TabControl, and I failed to figure out how to switch between two Templates depending on the type of message incoming (public/private). Binding custom properties and events to that was also something I could not find much of. –  Mar 19 '14 at 22:15
  • The template for the tab control just lets you have multiple rooms (same with an ItemControl). The public/private shouldn't affect that (since that is on the message level). – BradleyDotNET Mar 19 '14 at 22:16
  • 1
    @user3439733 yes, you need an ItemsControl. Read the linked article(s) about it. In WPF, any UI which displays 2 or more of the same "thing" (regardless what the "thing" is) is an ItemsControl. No way around that if you want clean, maintainable code and an easy-to-customize UI. – Federico Berasategui Mar 19 '14 at 22:17
  • To expound HighCore's point, you never want "repeated" controls in a WPF app. Their existence immediately shows the need for some collection container (like ItemsControl, and I believe TabControl and the others actually derive from ItemsControl) – BradleyDotNET Mar 19 '14 at 22:22
  • I've read it through, it's very complex but it does seem as if I'm treating WPF as if it was WinForms which obviously explains the frustration. I'm going to have to try out the MVVM example and see if I can make sense of that. The most I understand of it, is the Models, everything else is blurred to me. –  Mar 19 '14 at 22:36
  • Good plan, that should help you gain some traction on this problem. Good luck learning MVVM! – BradleyDotNET Mar 19 '14 at 22:51
  • Ok so drifting away from the original post, I followed the example given... and I don't see where it actually binds the DataTemplates at all. –  Mar 19 '14 at 23:41

2 Answers2

0

Sounds like a perfect place for a data template!

First off, you need a "ChatRoom" class that contains all the state information for a given room. Then your main ViewModel needs to have a collection of these objects. Finally, set up your tab control with a DataTemplate that is probably nearly identical to your current window.

The TabControl would look like:

<TabControl ItemsSource="{Binding ActiveRooms}">
  <TabControl.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
  </TabControl.ItemTemplate>
  <TabControl.ContentTemplate>
    <DataTemplate>
       ... (All your chat room stuff)
    </DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>

That way, whenever you create a new room (ActiveRooms should be an ObservableCollection, by the way) it automatically a new set of controls and binds them to the new room's instance properties.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Well the ItemTemplate would be more complex as it would contain the actual tab too, correct? Also I mentioned the public/private part because they contain different templates. For example a public chat would have a user list and a private chat would not. –  Mar 19 '14 at 22:33
  • That would require use of a DataTemplateSelector, or just have the user list visibility bound to an "IsPrivate" variable on the ChatRoom object. The Item template is just the header (another Q/A on SO, I can add the link to my answer if you are interested). The "tab" piece is contained within the control template. – BradleyDotNET Mar 19 '14 at 22:49
0

You can do it using MVVM pattern which is preferable when dealing with WPF. However, this requires some experience and a lot of mind-warping.

Luckily, you can always use classic approach if you are coming from the Windows Forms world. Just create an user control for the chat room which contains GUI, data, logic, event handlers, ...
Place instances of this chat room user control inside tab container and you are done.

Dusan
  • 5,000
  • 6
  • 41
  • 58