it-swarm.com.de

Wie ändere ich die Breite der MahApps.Metro-Dialogvorlagen?

Ich möchte die Basisvorlage der MahApps.Metro -Dialoge ändern (oder einen neuen Dialogtyp erstellen), weil ich sie in einem schmalen Anmeldefenster anzeigen möchte. Im Moment befinden sich fast alle zweiten Wörter in der Nachricht in einer neuen Reihe, aber es gibt schöne große Leerzeichen auf der rechten und linken Seite, die ich gerne reduzieren möchte.

Too wide padding on the sides

Ich habe in BaseMetroDialog.xaml festgestellt, dass der Nachrichtendialog vertikal in drei Teile unterteilt ist: 25% Leerzeichen auf der linken Seite, 50% für den Inhalt und 25% Leerzeichen auf der rechten Seite. Ich möchte diese Nummern ändern.

Aber wie könnte ich die Kontrollvorlage von BaseMetroWindow mit meiner neuen ändern?

10
user3126075

Erstellen Sie einfach Ihren eigenen Stil, der den Dialog Template überschreibt (und fügen Sie auch die DialogShownStoryboard hinzu).

<Style TargetType="{x:Type Dialog:BaseMetroDialog}"
        x:Key="NewCustomDialogStyle"
        BasedOn="{StaticResource {x:Type Dialog:BaseMetroDialog}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Dialog:BaseMetroDialog}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="DialogShownStoryboard">
                        <DoubleAnimation AccelerationRatio=".9"
                                            BeginTime="0:0:0"
                                            Duration="0:0:0.2"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1" />
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid Background="{TemplateBinding Background}">
                    <Border FocusVisualStyle="{x:Null}"
                            Focusable="False">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <ContentPresenter Grid.Row="0"
                                                Content="{TemplateBinding DialogTop}" />
                            <Grid Grid.Row="1">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="10*" />
                                    <ColumnDefinition Width="80*" />
                                    <ColumnDefinition Width="10*" />
                                </Grid.ColumnDefinitions>
                                <!--  Content area  -->
                                <Grid Grid.Column="1"
                                        Margin="0 10 0 0">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                        <RowDefinition Height="*" />
                                    </Grid.RowDefinitions>
                                    <TextBlock Grid.Row="0"
                                                FontSize="{DynamicResource DialogTitleFontSize}"
                                                Foreground="{TemplateBinding Foreground}"
                                                Text="{TemplateBinding Title}"
                                                TextWrapping="Wrap" />
                                    <ContentPresenter Grid.Row="1"
                                                        Content="{TemplateBinding Content}" />
                                </Grid>
                            </Grid>
                            <ContentPresenter Grid.Row="2"
                                                Content="{TemplateBinding DialogBottom}" />
                        </Grid>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="Loaded">
                        <EventTrigger.Actions>
                            <BeginStoryboard Storyboard="{StaticResource DialogShownStoryboard}" />
                        </EventTrigger.Actions>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Der Namespace ist hier

xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;Assembly=MahApps.Metro"

Verwenden Sie nun diesen benutzerdefinierten Stil, z. für ein benutzerdefiniertes Dialogfeld

<Dialog:CustomDialog x:Key="CustomDialogTest"
                        Style="{StaticResource NewCustomDialogStyle}"
                        Title="This dialog allows arbitrary content. It will close in 5 seconds."
                        x:Name="CustomTestDialog">
    <StackPanel>
        <TextBlock Height="30"
                    Text="This dialog allows arbitrary content. You have to close it yourself by clicking the close button below."
                    TextWrapping="Wrap"
                    Foreground="{DynamicResource AccentColorBrush}" />
        <Button Content="Close Me!" />
    </StackPanel>
</Dialog:CustomDialog>

Screenshot von der Hauptdemo

enter image description here

Update

Mit der neuesten Version von MahApps.Metro ist es jetzt möglich, z. der MessageDialog-Stil global.

<Style TargetType="{x:Type Dialog:MessageDialog}"
       x:Key="NewCustomMessageDialogStyle"
       BasedOn="{StaticResource {x:Type Dialog:BaseMetroDialog}}">
  <Setter Property="Template">
    <!-- the custom template for e.g. MessageDialog -->
  </Setter>
</Style>

<Style TargetType="{x:Type Dialog:MessageDialog}" BasedOn="{StaticResource NewCustomMessageDialogStyle}" />

enter image description here

Hoffentlich hilft das!

25
punker76

Ich habe eine Weile gebraucht, um das zu klären, aber für Neulinge wie mich ist hier meine vollständig dokumentierte Lösung zum Erstellen von benutzerdefinierten Dialogfeldern mit Mahapps und MVVM. Es gibt wahrscheinlich Aspekte, die verbessert werden könnten, aber das ist, was arbeitete für mich.

Deklarieren Sie Ihr Dialogressourcenwörterbuch in App.xaml, damit es global verfügbar ist

App.xaml

  <Application x:Class="MyAppName.App"
            xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:MyAppName"
            xmlns:Controls="clr-namespace:MahApps.Metro.Controls;Assembly=MahApps.Metro"
            xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;Assembly=MahApps.Metro"            

            >
     <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
               <ResourceDictionary>
               <ResourceDictionary  Source="DialogResource.xaml" />             
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
     </Application.Resources>
  </Application>

Das Ressourcenwörterbuch enthält den Ersetzungscode für die Vorlage für das benutzerdefinierte Dialogfeld

DialogResource.xaml

  <ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
                  xmlns:local="clr-namespace:MyAppName.MyResources"
                  xmlns:Controls="clr-namespace:MahApps.Metro.Controls;Assembly=MahApps.Metro"
                  xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;Assembly=MahApps.Metro"                    

                  >

     <!== Override default template for Mahapps custom dialog -->

     <Style TargetType="{x:Type Dialog:BaseMetroDialog}"
        x:Key="NewCustomDialogStyle"
        BasedOn="{StaticResource {x:Type Dialog:BaseMetroDialog}}">
        <Setter Property="Template">
            <!-- Custom template xaml code goes here -- see above StackOverflow answer from Punker76 --->
        </Setter>
     </Style>

  </ResourceDictionary>

Erstellen Sie ein WPF-Fenster mit dem Namen UserInputDialog, und ersetzen Sie all xaml-Code mit customdialog xaml. . Im Gebrauch der Caliburn Micro-Syntax werden die Schaltflächen an das Ansichtsmodell des Unterbelend-Dialogs gebunden (cal: Message.Attach =). Im Fall von dialog xaml-code muss ich die Tastenbindungen manuell angeben, da Caliburn Micro aus irgendeinem Grund nicht wie im Hauptansichtsmodell automatisch ist.

UserInputDialog.xaml

  <Dialog:CustomDialog  
                    x:Name="MyUserInputDialog"
                    x:Class="MyAppName.UserInputDialog"
                    Style="{StaticResource NewCustomDialogStyle}"
                    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
                    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
                    xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;Assembly=MahApps.Metro"
                    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;Assembly=MahApps.Metro"
                    xmlns:cal="http://www.caliburnproject.org"
                    xmlns:diag="clr-namespace:System.Diagnostics;Assembly=WindowsBase"

                    >

     <!--      , diag:PresentationTraceSources.TraceLevel=High        -->

     <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"  >

        <Label HorizontalAlignment="Center" Margin="10" Content="{Binding MessageText}" /> 

        <TextBox    x:Name="tbInput" 
                   Width="200"
                   Margin="10"
                   Content="{Binding UserInput}"
                   HorizontalAlignment="Center"
                   KeyDown="tbInput_KeyDown"                  
                   />

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="10,20" >

            <Button x:Name="butOK"
               Content="OK"
               Width="80"
               Margin="10,0"                
               HorizontalAlignment="Center"
               cal:Message.Attach="butOK"                
               />

            <Button x:Name="butCancel"
               Content="Cancel"             
               Width="80"
               Margin="10,0"
               HorizontalAlignment="Center"
               cal:Message.Attach="butCancel"    
               />



        </StackPanel>
     </StackPanel>

  </Dialog:CustomDialog>    

Und der Code-Behind für UserInputDialog:

UserInputDialog.xaml.cs

  using MahApps.Metro.Controls.Dialogs;
  using System;
  using System.Windows;
  using System.Windows.Controls;
  using System.Windows.Input;

  namespace MyAppName
  {
     public partial class UserInputDialog : CustomDialog
     {
        public UserInputDialog()
        {
            InitializeComponent();

            MinWidth = 300;
            MinHeight = 300;

            Loaded += Dialog_Loaded;
        }

     private void Dialog_Loaded(Object sender, RoutedEventArgs e)
     {
        tbInput.Focus();
     }


     private void tbInput_KeyDown(object sender, KeyEventArgs e)
     {
        //Not strictly MVVM but prefer the simplicity of using code-behind for this
        switch (e.Key)
        {

            case Key.Enter:
               if(this.DataContext != null) (dynamic)this.DataContext.butOK();
               break;

            case Key.Escape:
               if(this.DataContext != null) (dynamic)this.DataContext.butCancel();
               break;
        }

     }


  }
  }

Erstellen Sie eine Viewmodel-Klasse speziell für den Benutzereingabedialog

UserInputViewModel.cs

  using System;
  using System.Windows.Input;
  using Caliburn.Micro;
  using MyAppName.Models;
  using System.Security;

  namespace MyAppName.ViewModels
  {
     public class UserInputViewModel : PropertyChangedBase
     {

        private readonly ICommand _closeCommand;

        public string MessageText { get; set; }  // Message displayed to user

        public string UserInput { get; set; }   // User input returned

        public bool Cancel { get; set; }  // Flagged true if user clicks cancel button

        //Constructor
        public UserInputViewModel(Action<UserInputViewModel> closeHandler)
        {
            Cancel = false;
            _closeCommand = new SimpleCommand { ExecuteDelegate = o => closeHandler(this) };
        }

        public void butCancel()
        {
            Cancel = true;
            _closeCommand.Execute(this);
        }

        public void butOK()
        {
            Cancel = false;
            _closeCommand.Execute(this);
        }

        //-----------------
     }
  }

Erstellen Sie eine separate ICommand-Klasse, die in der Funktion zum Schließen des externen Dialogs über den Konstruktor für das Dialogfenster Ansichtsmodell übergeben wird

SimpleCommand.cs

  using System;
  using System.Windows.Input;

  namespace MyAppName.Models
  {
     public class SimpleCommand : ICommand
     {
        public Predicate<object> CanExecuteDelegate { get; set; }
        public Action<object> ExecuteDelegate { get; set; }

        public bool CanExecute(object parameter)
        {
            if (CanExecuteDelegate != null)
               return CanExecuteDelegate(parameter);
            return true; // if there is no can execute default to true
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            if (ExecuteDelegate != null)
               ExecuteDelegate(parameter);
        }
     }
  }

Und schließlich ist hier der Modellcode für die Hauptansicht, um das angepasste Dialogfeld anzuzeigen und die zurückgegebenen Benutzereingaben zu verarbeiten: -

MainViewModel.cs

  using MahApps.Metro.Controls.Dialogs;
  namespace MyAppName.ViewModels
  {
     /// <summary>
     /// The ViewModel for the application's main window.
     /// </summary>
     public class MainViewModel : PropertyChangedBase
     {


        private readonly IDialogCoordinator _dialogCoordinator;

        //Constructor
        public MainViewModel(IDialogCoordinator dialogCoordinator)
        {
            // Dialog coordinator provided by Mahapps framework 
            // Either passed into MainViewModel constructor to conform to MVVM:-

            _dialogCoordinator = dialogCoordinator;

            // or just initialise directly here
            // _dialogCoordinator = new DialogCoordinator();
        }



        public async void GetUserInput()
        {

            var custom_dialog = new UserInputDialog();

            custom_dialog.Height = 300;
            custom_dialog.Width = 400;

            var dialog_vm = new UserInputViewModel(async instance =>
            {
               await _dialogCoordinator.HideMetroDialogAsync(this, custom_dialog);
               //instance --> dialog ViewModel
               if (!(instance.Cancel || String.IsNullOrEmpty(instance.UserInput)) ProcessUserInput(instance.UserInput);
            });

            dialog_vm.MessageText = "Please type in your first name";

            custom_dialog.DataContext = dialog_vm;

            await _dialogCoordinator.ShowMetroDialogAsync(this, custom_dialog);

        }

        public ProcessUserInput(string input_message){
               Console.WriteLine("Users firstname is " + input_message);

        }
    }

  }
3
Hugh

Überschreiben Sie den Metrodialog-Stil und fügen Sie die Ressource im Metro-Fenster zusammen

<Style x:Key="newDialogStyle" BasedOn="{StaticResource MetroDialogStyle}"
           TargetType="{x:Type Dialogs:BaseMetroDialog}">
        <!-- ur design of Control Template -->
    </Style>

<Dialogs:CustomDialog Style="{StaticResource newDialogStyle}" Title="Custom Dialog which is awaitable">
        <StackPanel>
            <TextBlock Height="30" Text="This dialog allows arbitrary content. You have to close it yourself by clicking the close button below."
                           TextWrapping="Wrap"
                           Foreground="{DynamicResource AccentColorBrush}" />
            <Button Content="Close Me!"/>
        </StackPanel>
    </Dialogs:CustomDialog>
0
ReeganLourduraj

Eine andere Lösung finden Sie unter bug tracker : Verwenden Sie nicht die Content-Eigenschaft, sondern DialogTop. Zum Beispiel:

<dialogs:CustomDialog.DialogTop>
    <StackPanel>
        ....
    </StackPanel>
</dialogs:CustomDialog.DialogTop>

Fügen Sie Ihren benutzerdefinierten Inhalt (z. B. StackPanel) in DialogTop ein und fertig.

0