Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TabItem Binding WPF

Tags:

c#

binding

wpf

I'm just learning WPF and I could use some help. I have an application which use TabControl and dynamically generates new tabs,on each Tab I have one TextBox and now I'd like to add an undo button to the tool bar which is not the part of the tab (VisualStudio like). The undo button has to work only on the TextBox wich is on the active tab and if there is no tab or the undo can't be executed it will be disabled. And I have no idea how to bind these two items (The tab content has it own xaml file).

Only thing I succeed is adding an click eventHandler to the MenuItem and then finding the text box on the active tab by name, but now I can't enable/disable like I'd wish.

I hope it is understandable. Thanks for any help

like image 238
Zviri Avatar asked Jun 03 '10 15:06

Zviri


Video Answer


1 Answers

I've made an example to illustrate the "right WPF way" to go about this scenario. Again, it might not match the code you already have, but it should give you some ideas on how to adapt your code. First, the code-behind:

public partial class TabItemBinding : Window
{
    public ObservableCollection<TextItem> Items { get; set; }

    public TabItemBinding()
    {
        Items = new ObservableCollection<TextItem>();

        Items.Add(new TextItem() { Header = "1", Content = new TextBox() { Text = "First item" } });
        Items.Add(new TextItem() { Header = "2", Content = new TextBox() { Text = "Second item" } });
        Items.Add(new TextItem() { Header = "3", Content = new TextBox() { Text = "Third item" } });

        InitializeComponent();
    }
}

public class TextItem
{
    public string Header { get; set; }
    public FrameworkElement Content { get; set; }
}

Nothing crazy here, I'm just creating a model class and setting up a collection of that class. The real goodness happens in the XAML:

<Window x:Class="TestWpfApplication.TabItemBinding"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TabItemBinding" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <ToolBar Grid.Row="0">
        <Button Command="Undo">Undo</Button>
    </ToolBar>

    <TabControl Grid.Row="1" ItemsSource="{Binding Items}">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding Header}"/>
                <Setter Property="Content" Value="{Binding Content}"/>
            </Style>
        </TabControl.ItemContainerStyle>
    </TabControl>
</Grid>

I hook up the Button to ApplicationCommands.Undo, which will automatically take care of the undo for us as long as we have an active editing TextBox. The TabControl itself is bound to the collection we made in the code-behind, which will provide a header and some text to edit. And any edits we make will be undo-able. The result:

Screenshot http://img706.imageshack.us/img706/2866/tabitembinding.png

By the way, it's important to note that the undo command will automatically disable itself if there is not an active editing context. So if there are no tab pages, it will be disabled without any extra code on our part.

like image 57
Charlie Avatar answered Oct 21 '22 22:10

Charlie