C# WPF TabControl dynamischer Button zum schließen

-Rayz-

Lieutenant
Registriert
Okt. 2010
Beiträge
897
Hallo,

ich bin mal wieder im leidigen Thema WPF und xaml unterwegs. Ich nutze Caliburn und möchte zwei Typen von Tabs haben. Einmal ein Main Tab für eine Liste und dann soll sich bei einem Button Event immer ein weiterer Tab öffnen um der Liste Einträge hinzuzufügen. Das klappt auch alles ganz gut aber mein Main Tab soll natürlich NICHT die Möglichkeit haben, geschlossen zu werden.
Im Code kann ich da einfach dem ViewModel ein CanClose(false) zuweisen. Problem ist aber, dass das Tab Item dennoch den Button zum schließen anzeigt. Ich möchte diesen Button aber nur dort haben, wo ich Einträge der Liste hinzufügen kann.
Mein xaml dazu sieht bisher so aus:

Code:
 <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="10"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="10"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <StackPanel  Grid.Column="1" Grid.Row="0">
            <Button x:Name="CloseAll" Content="Close All" DockPanel.Dock="Top" />
            <Button x:Name="AddMitarbeiter" Content="AddMitarbeiter" DockPanel.Dock="Top" />
            <Button x:Name="OpenTab"
                Content="Open Tab"
                DockPanel.Dock="Top" />
        </StackPanel>
        <DockPanel Grid.Column="1" Grid.Row="1">
            <TabControl x:Name="Items">
                <TabControl.ItemContainerStyle>
                    <Style TargetType="TabItem">
                        <Setter Property="FontSize" Value="20"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="TabItem">
                                    <Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="Gainsboro" CornerRadius="4,4,0,0" Margin="2,0">
                                        <ContentPresenter x:Name="ContentSite"
                                        VerticalAlignment="Center"
                                        HorizontalAlignment="Center"
                                        ContentSource="Header"
                                        Margin="10,2"/>
                                    </Border>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsSelected" Value="True">
                                            <Setter TargetName="Border" Property="Background" Value="LightSkyBlue" />
                                        </Trigger>
                                        <Trigger Property="IsSelected" Value="False">
                                            <Setter TargetName="Border" Property="Background" Value="White" />
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </TabControl.ItemContainerStyle>
                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Cursor="Hand" VerticalAlignment="Top" Height="36">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="18" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="0" Text="{Binding DisplayName}"/>
                            <Button Grid.Column="1" cal:Message.Attach="DeactivateItem($dataContext, 'true')">
                                <Button.Style>
                                    <Style>
                                    </Style>
                                </Button.Style>
                            </Button>
                        </Grid>
                    </DataTemplate>
                </TabControl.ItemTemplate>
            </TabControl>
        </DockPanel>
    </Grid>

Falls erforderlich hier noch mein ViewModel:

C#:
    public class ShellViewModel : Conductor<IScreen>.Collection.AllActive
    {
        int count = 1;
        private MitarbeiterViewModel mitarbeiterViewModel;
        public ShellViewModel()
        {
            this.mitarbeiterViewModel = new MitarbeiterViewModel
            {
                DisplayName = "Mitarbeiter"
            };
            ActivateItem(this.mitarbeiterViewModel);
        }
        public void OpenTab()
        {
            Items.Add(new TabViewModel{
                DisplayName = "Tab " + count++
            });

        }

        public void CloseAll()
        {
            Items.ToList().ForEach(x => {
                if (x is TabViewModel)
                {
                    (x as TabViewModel).TestCall();
                }
            });
        }

        public void AddMitarbeiter()
        {
          
        }
    }

Bin halt noch am rumprobieren...
 
Ich bin mir nicht ganz sicher wie das was du da machst funktionieren soll, weil ich Caliburn nicht kenne, aber du willst den Butten in Codezeile 55 bis 60 beim ersten Tab nicht anzeigen, oder? Ich würde irgendwie auf das Loaded/DataContextChanged-Event reagieren und basierend auf dem DataContext entscheiden ob ich den Butten anzeige oder nicht, indem ich die Visibility des Buttons auf Visible oder Collapsed setzt.
 
Zuletzt bearbeitet:
Also müsste ich das irgendwie Code Behind machen? Kann ich nicht in xaml irgendwie ein Binding auf den Typ hinbekommen...? Diesen Button brauch ich ja nur dann, wenn der Typ ein TabViewModel ist.
 
Das hab ich auf Stackoverflow gefunden, aber selber nicht zum Laufen gebracht:
https://stackoverflow.com/questions/61869391/isvisible-in-caliburnmicro-not-linking

Ansonsten funktioniert es auch so:
Code:
<Button Grid.Column="1" cal:Message.Attach="DeactivateItem($dataContext, 'true')"
        Visibility="{Binding RemoveButtonVisibility}">
    <Button.Style>
        <Style>
        </Style>
    </Button.Style>
</Button>
C#:
class MitarbeiterViewModel : Screen
{
    public Visibility RemoveButtonVisibility { get; } = Visibility.Collapsed;

    /* ... */
}
 
  • Gefällt mir
Reaktionen: -Rayz-
Perfekt. Klappt wunderbar mit der Visibility. Danke dir
 
Zurück
Oben