WPF (1) Grundlegende WPF-Steuerelemente und -Layout

​ WPF (Windows Presentation Foundation) ist ein von Microsoft eingeführtes Windows-basiertes Benutzeroberflächen-Framework. Es wird auf Chinesisch in „Windows Presentation Foundation“ übersetzt und ist Teil von .NET Framework 3.0. WPF ähnelt dem technischen Framework von WinForm, aber im Vergleich zu WinForm erweitert WPF die meisten Grundfunktionen leistungsfähiger und führt die XAML-Markup-Sprache ein, die die Front-End- und Back-End-Trennung von Entwicklern und Designern wirklich realisiert und abgeleitet Eine Reihe von MVVM-Entwicklungsframeworks. Einige Referenzen lauten wie folgt:

1. Einführung in die Grundsteuerung

1. Vererbungsbeziehung des WPF-UI-Elements


Fügen Sie hier eine Bildbeschreibung ein

2. Grundlegende Steuerelemente

2.1 TextBlock

Einfach ausgedrückt ist TextBlock ein Textblock, der zur Darstellung von Textinhalten verwendet wird. TextBlock kann seine Text-Eigenschaft oder Inline-Flow-Inhaltselemente im Inline-Format (ähnlich der HTML-Sprache) enthalten. Diese kleinen steuerelementähnlichen Strukturen werden von der Inline-Klasse geerbt und können inline als Teil des Textes gerendert werden, z. B. fett, fett, kursiv und kursiv , Unterstreichen, Unterstreichen usw.).

- Foreground : 获取或设置要应用到 TextBlock 的文本内容的 Brush(文本颜色刷)。
- Background : 获取或设置要用于填充内容区域背景的 Brush(文本块背景颜色刷)。
- TextTrimming : 获取或设置在内容超出内容区域时要采用的文本剪裁行为(CharacterEllipsis字符边界裁剪、None不裁剪、WordEllipsis单词边界裁剪)。
- TextWrapping : 获取或设置 TextBlock 对文本进行换行的方式(Wrap自动换行、NoWrap不换行)。
- Text : 获取或设置 TextBlock 的文本内容,等效于标签中间放置文字。
- Inlines : 获取包含顶级 Inline 元素的 InlineCollection,前者构成 TextBlock 的内容。
<!--TextBlock Inlines的XML格式-->
<TextBlock Margin="5" TextWrapping="Wrap" TextAlignment="Center">
     This is a <Bold>TextBlock</Bold>,we are text the <Italic Foreground="Blue">inline elements</Italic>
     <Span TextDecorations="Underline" Background="Silver">Look me,Hahahaha</Span>
</TextBlock>

Fügen Sie hier eine Bildbeschreibung ein

//TextBlock Inlines的代码格式
TextBlock textBlock1 = new TextBlock();

textBlock1.TextWrapping = TextWrapping.Wrap;
textBlock1.TextAlignment = TextAlignment.Center;

textBlock1.Inlines.Add("This is a");
textBlock1.Inlines.Add(new Blob(new Run("TextBlock")));
textBlock1.Inlines.Add(",we are text the");
textBlock1.Inlines.Add(new Italic(new Run("inline elements")){
    
     Foreground = Brushes.Blue });
...

2.2 Etikett

Label stellt die Textbeschriftung des Steuerelements dar, ähnlich wie TextBlock. Aber das Label verwendet die Content-Eigenschaft anstelle der Text-Eigenschaft. Dies liegt daran, dass jede Art von Steuerelement innerhalb des Labels platziert werden kann, nicht nur Text. Natürlich kann der Inhalt auch ein String sein.

- 访问键/助记符:用于启用对控件的快速键盘访问,即通过访问键可以快速聚焦到相关的控件上。Label支持助记符绑定。
- Label助记符配置:在应为访问密钥的字符之前添加下划线,然后按住[Alt]键快速定位。 如果内容包含多个下划线字符,则只有第一个字符转换为访问键,其他下划线显示为普通文本。第一个下划线使用两个连续下划线表示普通的下划线文本内容。
- Foreground : 前景色背景
- Content : 设置Label内容,类型为Object
- Target : 获取或设置当用户按下标签的访问键时获得焦点的元素。
<Window x:Class="WpfTutorialSamples.Basic_controls.LabelControlAdvancedSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LabelControlAdvancedSample" Height="180" Width="250">
    
	<StackPanel Margin="10">
		<Label Target="{Binding ElementName=txtName}">
            <!--Label内部Content包含堆叠对象-->
			<StackPanel Orientation="Horizontal">
				<Image Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_green.png" />
                <!--AccessText控件用下划线来指定用作访问键的字符并呈现-->
				<AccessText Text="__Na_me:" />
			</StackPanel>
		</Label>
		<TextBox Name="txtName" />
		<Label Target="{Binding ElementName=txtMail}">
			<StackPanel Orientation="Horizontal">
				<Image Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_blue.png" />
				<AccessText Text="_Mai_l:" />
			</StackPanel>
		</Label>
		<TextBox Name="txtMail" />
	</StackPanel>
    
</Window>

2.3 TextBox

Das TextBox-Steuerelement ist das grundlegendste Texteingabesteuerelement in WPF. Es ermöglicht die Anzeige oder Bearbeitung von unformatiertem Text wie in einem Editor.

- AcceptsReturn : 获取或设置一个值,该值指示在用户按 ENTER 键时文本编辑控件如何响应(如果按ENTER键可在当前光标位置处插入新行,则为true;否则将忽略ENTER键)
- TextWrapping : 获取或设置文本框中文本的换行方式
- Text : 获取或设置文本框的文本内容
- SpellCheck : 获取一个 SpellCheck 对象,来设置拼写检查错误
- Language : 该属性指示拼写检查器使用的语言
- IsReadOnly : 文本框是否只读
- TextBox的选择参数属性:
	- SelectionStart : 获取或设置当前选择的起始位置的字符索引(当前光标位置或是否有选择)
	- SelectionLength : 获取或设置一个值,该值指示文本框中当前选择的字符数(当前选择的长度,否则为0)
	- SelectedText : 获取或设置文本框中当前选择的内容(当前选择的字符串,否则为空)
- SelectionChanged : 订阅SelectionChanged事件,在文本选择改变时发生
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBoxSelectionSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TextBoxSelectionSample" Height="150" Width="300">
	<DockPanel Margin="10">
		<TextBox SelectionChanged="TextBox_SelectionChanged" DockPanel.Dock="Top" />
		<TextBox Name="txtStatus" AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True" />
	</DockPanel>
</Window>
namespace WpfTutorialSamples.Basic_controls
{
    
    
	public partial class TextBoxSelectionSample : Window
	{
    
    
		public TextBoxSelectionSample()
		{
    
    
			InitializeComponent();
		}

		private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
		{
    
    
			TextBox textBox = sender as TextBox;
			txtStatus.Text = "Selection starts at character #" + textBox.SelectionStart + Environment.NewLine;
			txtStatus.Text += "Selection is " + textBox.SelectionLength + " character(s) long" + Environment.NewLine;
			txtStatus.Text += "Selected text: '" + textBox.SelectedText + "'";
		}
	}
}

Bild

2.4 Taste

Button stellt ein Windows-Schaltflächensteuerelement dar, das auf das Click-Ereignis reagieren kann. Um dieselben Eigenschaftseinstellungen auf mehrere Button-Steuerelemente anzuwenden, verwenden Sie die Style-Eigenschaft. Sie können auch die Standard-ControlTemplate ändern, um dem Steuerelement ein einzigartiges Aussehen zu verleihen.

- Content : 设置Button内容,类型为Object。可以包括字符串或一些复杂类型
- Foreground, Background, FontWeight : 设置Button控件文字的样式
- Padding : 获取或设置控件内部的填充边距
- 事件
	- Click : 在单击 Button 时发生事件
	- ClickMode : 获取或设置 Click 事件何时发生。
<Button Padding="5">  
    <StackPanel Orientation="Horizontal">  
    <Image Source="/WpfTutorialSamples;component/Images/help.png" />  
    <TextBlock Margin="5,0">Help</TextBlock>  
    </StackPanel>  
</Button>

Bild

2.5 Listensammlungskontrolle

Ein Listensammlungssteuerelement stellt ein Steuerelement dar, das zur Darstellung einer Reihe von Elementen/Daten verwendet werden kann. Die Listensammlungssteuerelemente in WPF werden von der ItemsControl-Klasse abgeleitet und gehören zu den Elementen der ItemsControl-Familie, z. B. ListBox und ComboBox. Hier nehmen wir ItemsControl und ListBox als Beispiele für die Kontrollanalyse.

(1)ItemsControl

ItemsControl ist das einfachste Steuerelement für die Präsentation von Datenlisten, das Listendaten fast einfach durchläuft und präsentiert, ohne eine andere Elementauswahl bereitzustellen (ListBox kann eine Elementauswahl durchführen). ItemsControl erbt von der Control-Klasse, sodass seine Listensammlungsdaten im Wesentlichen nur ein Teil des Inhalts sind, der im Steuerelement enthalten ist. ItemsControl ist nicht nur das Element der obersten Ebene der ItemsControl-Familie, sondern wird auch häufig als benutzerdefiniertes Listensteuerelement (Definitionsvorlage) verwendet.

  • Automatisches Umschließen der ItemsControl-Familie

​ - Das herausragendste Merkmal der ItemsControl-Familie besteht darin, dass sie automatisch den Artikelcontainer (Item Container) verwendet, um jeden Dateninhalt ihrer Listensammlung zu umschließen. Jeder ItemsControl-Typ hat seinen entsprechenden Elementcontainertyp. Beispielsweise ist der Elementcontainer von ListBox ein ListBoxItem-Steuerelement; der Elementcontainer von ComboBox ist ein ComboBoxItem-Steuerelement.

​ - Item Container ist im Wesentlichen ein Steuerelement, von dem die meisten von der ContentControl-Klasse erben (z. B. ListBoxItem), was auch bedeutet, dass es ein einzelnes Objekt eines beliebigen Typs (z. B. eine Zeichenfolge, ein Bild oder ein Panel) enthalten kann.

​ - Wenn wir die Sammlungsdaten als Inhalt an ItemsControl übermitteln, verwendet ItemsControl diese Sammlung nicht direkt, sondern verwendet zunächst das entsprechende Elementcontainer-Steuerelement, um jedes Datenelement in der Sammlung einzeln zu verpacken, und packt dann den verpackten Elementcontainer Die Liste wird als Gesamtinhalt des ItemsControl dargestellt. Dies hat den Vorteil, dass wir nicht nur das Erscheinungsbild von ItemsControl definieren können, sondern auch bequem das Erscheinungsbild jedes Datenelements definieren können! Und der Sammlungsdatentyp von ItemsControl kann unterschiedlich sein.

​ - Für jedes Datenelement im ItemsControl kann explizit ein Item-Container erstellt werden, dies ist jedoch nicht erforderlich. Denn wenn der Elementcontainer nicht explizit erstellt wird, umschließt ItemsControl automatisch den Elementcontainer für den Inhalt jedes Datenelements.

 <ListBox>
	<ListBoxItem>ListBox Item 1</ListBoxItem>
	<ListBoxItem>ListBox Item 2</ListBoxItem>
	<ListBoxItem>ListBox Item 3</ListBoxItem>
	<ListBoxItem>ListBox Item 4</ListBoxItem>
</ListBox>

<!--              等价于            -->

<ListBox>
	<system:String>ListBox Item 1</system:String>
	<system:String>ListBox Item 2</system:String>
	<system:String>ListBox Item 3</system:String>
	<system:String>ListBox Item 4</system:String>
</ListBox>
  • Eigenschaften der ItemsControl-Klasse
public class ItemsControl : Control,IContainItemStorage,IAddChild
- 属性:
	- DataContext: 获取或设置元素参与数据绑定时的数据上下文。
	- DisplayMemberPath: 获取或设置源对象上的值的路径,以用作对象的可视表示形式。(只能显示简单的字符串数据)
	- HasItems: 获取一个值,该值指示 ItemsControl 是否包含项。
	- ItemContainerStyle: 获取或设置应用于为每个项生成的容器元素的 Style(设置其Item Container的Style)。
	- Items: 获取用于生成 ItemsControl 的内容的集合。
	- ItemsPanel: 获取或设置模板,该模板定义对项的布局进行控制的面板(默认值是一个纵向排列的指定StackPanel)
	- ItemsSource: 获取或设置用于生成 ItemsControl 的内容的集合(常用于数据绑定,ItemsSource设置属性后,集合Items是只读且固定大小)
	- ItemStringFormat: 获取或设置一个复合/格式化字符串,如果 ItemsControl 中的项显示为字符串,则用于指定如何格式化这些项。(仅用于string数据项)
	- ItemTemplate: 获取或设置用来显示[每个项]的 DataTemplate。
	- Template: 获取或设置控件模板。(整个ItemsControl的样式模板,非数据项)

(2)ListBox

​ Das ListBox-Steuerelement erbt vom Selector unter dem ItemsControl. Neben der Anzeige einer Reihe von Datenelementen in einer Liste kann die ListBox Benutzern auch die [Auswahl von Elementen] aus ihren untergeordneten Elementen ermöglichen.

public class ListBox : Selector
- 属性:
	- 继承 ItemsControl 的大部分属性
	- SelectedIndex: 获取或设置当前选择中第一项的索引,如果选择为空,则返回负一(-1)。
	- SelectedItem: 获取或设置当前选择中的第一项(Object),或者,如果选择为空,则返回 null。
	- SelectedItems: 获取当前选定的所有项集合(IList)。
	- SelectedValue: 获取或设置通过使用 SelectedValuePath 而获取的 SelectedItem 的路径值。当调用SelectedValue时,ListBox先找到选中的Item所对应的数据对象,然后把SelectedValuePath的值当作数据对象的属性名称并把这个属性值取出来。
	- SelectedValuePath: 获取或设置用于从 SelectedItem 中获取 SelectedValue 的路径/属性名(string)。
	- SelectionMode: 获取或设置 ListBox 的选择行为。默认值为 Single 选择。
		- Extended: 用户可以按下 Shift 键来选择多个连续项。
		- Multiple: 用户可以选择多个项而无需按下修改键。
		- Single: 用户一次只能选择一项。
- 事件:
	- SelectionChanged:当 Selector 的选择更改时发生。
namespace WPF_Demo
{
    
    
    public partial class MainWindow : Window
    {
    
    
        public MainWindow()
        {
    
    
            InitializeComponent();

            List<Employee> empList = new List<Employee>()
            {
    
    
                new Employee(){
    
    Id=1,Name="Tim",Age=30},
                new Employee(){
    
    Id=2,Name="Tom",Age=26},
                new Employee(){
    
    Id=3,Name="Kitty",Age=28},
                new Employee(){
    
    Id=4,Name="Lisa",Age=30},
                new Employee(){
    
    Id=5,Name="Krito",Age=36}
            };

            this.listBoxEmplyee.DisplayMemberPath = "Name";
            this.listBoxEmplyee.SelectedValuePath = "Id";
            this.listBoxEmplyee.ItemsSource = empList;
        }

        private void listBoxEmplyee_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
    
    
            ListBox lst = sender as ListBox;
            if (lst != null)
            {
    
    
                int id = (int)lst.SelectedValue;
                int index = lst.SelectedIndex;
                MessageBox.Show("Id=" + id + ",Index=" + index);
            }
        }
    }


    public class Employee
    {
    
    
        public int Id {
    
     get; set; }
        public string Name {
    
     get; set; }
        public int Age {
    
     get; set; }
    }

}

Fügen Sie hier eine Bildbeschreibung ein

3. Gemeinsame Eigenschaften allgemeiner Steuerelemente in WPF

3.1 ToolTip-Eingabeaufforderungsobjekt

Die FrameworkElement- Klasse verfügt über eine ToolTip- Eigenschaft, von der fast alle WPF-Steuerelemente erben. Diese Eigenschaft wird verwendet, um das Tooltip- Objekt (UI, Objekt) abzurufen oder festzulegen, das für dieses Element in der Benutzeroberfläche angezeigt wird, z. B. eine einfache Eingabeaufforderungszeichenfolge oder ein komplexes Eingabeaufforderungslayout. Darüber hinaus können in Kombination mit der ToolTipService-Klasse eine Reihe interessanter Verhaltensweisen implementiert werden, die sich auf den Tooltip auswirken, z. B. die ShowDuration- Eigenschaft, die die Dauer des Tooltips verlängert usw.

<Window x:Class="WpfTutorialSamples.Control_concepts.ToolTipsAdvancedSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ToolTipsAdvancedSample" Height="200" Width="400" UseLayoutRounding="True">
    <DockPanel>
        <ToolBar DockPanel.Dock="Top">
        	<!--简单字符串提示-->
            <Button ToolTip="Create a new file">
                <Button.Content>
                    <Image Source="/WpfTutorialSamples;component/Images/page_white.png" Width="16" Height="16" />
                </Button.Content>
            </Button>
            <Button>
                <Button.Content>
                    <Image Source="/WpfTutorialSamples;component/Images/folder.png" Width="16" Height="16" />
                </Button.Content>
                <!--复杂提示对象,布局Panel-->
                <Button.ToolTip>
                    <StackPanel>
                        <TextBlock FontWeight="Bold" FontSize="14" Margin="0,0,0,5">Open file</TextBlock>
                        <TextBlock>
                        Search your computer or local network
                        <LineBreak />
                        for a file and open it for editing.
                        </TextBlock>
                        <Border BorderBrush="Silver" BorderThickness="0,1,0,0" Margin="0,8" />
                        <WrapPanel>
                            <Image Source="/WpfTutorialSamples;component/Images/help.png" Margin="0,0,5,0" />
                            <TextBlock FontStyle="Italic">Press F1 for more help</TextBlock>
                        </WrapPanel>
                    </StackPanel>
                </Button.ToolTip>
            </Button>
        </ToolBar>

        <TextBox>
            Editor area...
        </TextBox>
    </DockPanel>
</Window>

Bild

3.2 Textwiedergabe

Microsoft hat zahlreiche Optimierungen für die WPF-Textwiedergabe-Engine in .NET Framework 4.0 vorgenommen und die TextOptions- Klasse und zugehörige Eigenschaften eingeführt

- TextOptions.TextFormattingMode : 选择用 Ideal(默认值)或 Display(更清晰)
- TextOptions.TextRenderingMode : 控制显示文本所用的抗锯齿算法
<Label TextOptions.TextFormattingMode="Display" FontSize="9">TextFormattingMode.Ideal, small text</Label>
<Label TextOptions.TextRenderingMode="Auto" FontSize="9">TextRenderingMode.Auto, small text</Label>

2. Ressourcen und Konverter

1. WPF-Ressourcen

1.1 Ressourcendefinition

Eine Ressource ist eine Sammlung von Objektdaten, die an verschiedenen Stellen in der Anwendung wiederverwendet werden können. Alle Daten, Steuerelemente, Zeichenfolgen usw. können als Ressourcen gespeichert werden, sodass Sie Daten an einem Ort speichern und überall verwenden können, was sehr praktisch ist. Die Schnittstellenelemente von WPF verfügen alle über ein Resources-Attribut vom Typ ResourceDictionary, das Datenressourcen in Form von „Schlüssel-Wert“-Paaren speichern kann. Jede Ressource in einem Ressourcenwörterbuch muss einen eindeutigen Schlüssel haben. Beim Definieren einer Ressource im Markup kann über die Direktive x:Key ein eindeutiger Schlüssel zugewiesen werden. Normalerweise ist dieser Schlüssel eine Zeichenfolge.

(1) Kontrollbereich: Das vom Steuerelement definierte Ressourcenwörterbuch kann nur innerhalb des aktuellen Steuerelements <StackPanel.Resources>…</StackPanel.Resources> verwendet werden

(2) Fenster-/Seitenbereich: <Window.Resources> ...</Window.Resources> kann nur im aktuellen Fenster/der aktuellen Seite verwendet werden

(3) Globale Anwendung: global verfügbar <Application.Resources>…</Application.Resources>

1.2 Ressourcennutzung

WPF sucht automatisch nach der angegebenen Ressource vom aktuellen Bereichskontrollelement (Kontrollbereich) zum Fenster und dann zu App.xaml entlang der UI-Struktur von unten nach oben und stoppt, wenn es sie findet, aber es wird nicht nach unten gesucht. Ressourcen und Ressourcenwörterbücher können nicht nur den Stil von Elementen definieren, sondern auch Ressourcenvorlagen, Storyboards, Trigger usw. definieren, was Coderedundanz und wiederholte Definition desselben Stils erleichtert, wenn Stile für viele gleiche Steuerelemente definiert werden.

  • Statische Ressourcen: Suche zur Kompilierzeit . Durch die Verwendung der StaticResource-Markup-Erweiterung zum Erstellen von Referenzen (unter Verwendung von Markup-Erweiterungen zum Verarbeiten von Attributzeichenfolgen und zum Zurückgeben von Objekten an Programm Wird einmal zur Laufzeit geladen.

  • Dynamische Ressourcen: Suche zur Laufzeit , erstellen Sie Referenzen mithilfe der DynamicResource-Markup-Erweiterung. Erstellt während der ersten Kompilierung einen temporären Ausdruck und verschiebt dadurch die Suche nach der Ressource, bis der angeforderte Ressourcenwert tatsächlich zum Erstellen des Objekts benötigt wird. Die Suche nach dieser Ressource verhält sich wie eine Laufzeitsuche, was sich auf die Leistung auswirkt . Verwenden Sie in Ihrer Anwendung so viele statische Ressourcen wie möglich und dynamische Ressourcen nur bei Bedarf.

(1) XAML-Deklaration:<子元素 (对应)属性名=”{StaticResource 资源标记名}” /> Oder <子元素 (对应)属性名=”{DynamicResource 资源标记名}” />XAML stimmt automatisch mit dem Datentyp überein, sodass die Konvertierung nicht erzwungen werden muss. Wenn der Typ nicht übereinstimmt, wird eine Ausnahme ausgelöst.

(2) Code-Referenz:

  • string text = (string)this.FindResource("str");Der Wert des Ressourcenwörterbuchs ist Object und muss zwangsweise konvertiert werden. Mit der FindResource-Methode wird vom unteren Ende des UI-Baums nach oben gesucht

  • string text1 = (string)this.Resources["str"]; Der Wert des Ressourcenwörterbuchs ist Object und muss zwangsweise konvertiert werden. Die Resources-Methode dient nur dazu, nach dem Ressourcenwörterbuch dieses Steuerelements zu suchen

1.3 Ressourcenzusammenführung

(1) Definieren Sie das Ressourcenwörterbuch

Zusätzlich zur Definition lokaler Ressourcenwörterbücher innerhalb der oben genannten Steuerelemente/Fenster können wir Ressourcenwörterbücher auch unabhängig voneinander für die Verwendung zwischen verschiedenen Anwendungen/verschiedenen Projekten definieren. Die ResourceDictionary-Klasse stellt eine Hashtabellen-/Wörterbuchimplementierung (Karte von Schlüssel-Wert-Paaren) bereit, die WPF-Ressourcen enthält, die von Komponenten und anderen Elementen einer WPF-Anwendung verwendet werden. VS2019 bietet ein Erstellungselement zum Hinzufügen einer Ressourcendatei dictionary.xaml . Das Ressourcenwörterbuch wird auf die gleiche Weise wie Ressourcen geschrieben. Definieren Sie Ihre Ressourcen einfach direkt in der Datei.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WPF_Demo">

    <Style TargetType="TextBox">
        <Setter Property="FontFamily" Value="楷体"></Setter>
        <Setter Property="FontSize" Value="50"></Setter>
        <Setter Property="Foreground" Value="Red"></Setter>
    </Style>
</ResourceDictionary>

(2) Ressourcenzusammenführung

​ Das neu definierte unabhängige Ressourcenwörterbuch kann nicht direkt verwendet werden, da das Wörterbuch noch nicht von WPF erkannt werden kann. Wir müssen es zusammenführen und dem entsprechenden Steuerelement-/Fenster-/APP-Bereich hinzufügen und die verwendete Zusammenführungseigenschaft ist MergedDictionaries . MergedDictionaries ist eine Eigenschaft der ResourceDictionary-Klasse, die ein ResourceDictionary-Auflistungstyp ist.

Normalerweise gibt jedes ResourceDictionary in der MergedDictionaries- Auflistung eine Source- Eigenschaft an. Der Wert von Source sollte ein Uniform Resource Identifier (URI) sein, der in den Speicherort der zusammenzuführenden Ressourcendatei aufgelöst wird. Das Ziel dieses URI muss eine andere XAML-Datei mit einem ResourceDictionary als Stammelement sein.

  • In einem einzigen Projekt zusammenführen
<ResourceDictionary>
     <ResourceDictionary.MergedDictionaries>
         <!--<ResourceDictionary Source="资源字典路径"/>-->
           <ResourceDictionary Source="/Dictionarys/ColorDictionary.xaml"/>
           <ResourceDictionary Source="..."/>
     </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
  • Mehrere Projekte zusammenführen
<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
       <!--<ResourceDictionary Source="/项目名;component/资源字典路径"/>-->
       <ResourceDictionary Source="/CommonModel;component/Dictionarys/PathDictionary.xaml"/>
       <ResourceDictionary Source="..."/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

2. Geben Sie Konverter ein

Verweise:

2.1 Das Konzept des Konverters

​ Wertkonverter werden oft zusammen mit der Datenbindung verwendet, um Daten zwischen verschiedenen Typen individuell zu konvertieren und sie auf der gebundenen Benutzeroberfläche anzuzeigen. Der WPF-Datenkonverter muss die IValueConverter-Schnittstelle oder die IMultiValueConverter-Schnittstelle (Mehrwegebindung) implementieren. Es müssen lediglich zwei Methoden implementiert werden: Mit Convert() und ConvertBack() wird der Wert in das Zielformat und wieder zurück konvertiert.

namespace System.Windows.Data
{
    
    
    public interface IValueConverter
    {
    
    
        // 摘要: 数据绑定引擎在将值从绑定源传播到绑定目标时会调用此方法,即源属性传给目标属性时
        // 参数:
        //   value: 绑定源生成的值。
        //   targetType: 绑定目标属性的类型。
        //   parameter: 要使用的转换器参数。
        //   culture: 要用在转换器中的区域化/国际化信息。
        // 返回结果:
        //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
        object Convert(object value, Type targetType, object parameter, CultureInfo culture);

        // 摘要: 数据绑定引擎在将值从绑定目标传播到绑定源时调用此方法,此方法的实现必须是Convert方法的反向实现。
        // 参数:
        //   value: 绑定源生成的值。
        //   targetType: 绑定目标属性的类型。
        //   parameter: 要使用的转换器参数。
        //   culture: 要用在转换器中的区域化/国际化信息。
        // 返回结果:
        //     转换后的值。 如果该方法返回 null,则使用有效的 null 值。
        object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
    }
}

2.2 Konverter-Implementierungsbeispiel

Hintergrund: Binden Sie die Zeichenfolge, konvertieren Sie automatisch die entsprechende Farbe und zeigen Sie sie auf der Benutzeroberfläche an. Die spezifische Implementierung lautet wie folgt

(1) Konverterimplementierung

namespace WPF_Demo.Convert
{
    
    
    [ValueConversion(typeof(string), typeof(SolidColorBrush))]
    class DemoConvert : IValueConverter
    {
    
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
    
    
            string str = value.ToString().ToLower();
            if (str.Equals("x-red"))
            {
    
    
                return new SolidColorBrush(Color.FromRgb(222, 32,37));
            }else if (str.Equals("x-blue"))
            {
    
    
                return new SolidColorBrush(Color.FromRgb(19, 21, 190));
            }
            return new SolidColorBrush(Color.FromRgb(0, 0, 0));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
    
    
            throw new NotImplementedException();
        }
    }
}

(2) Verwendung der XAML-Schnittstelle

  • Führen Sie den Convert-Namespace ein: xmlns:cv="clr-namespace:WPF_Demo.Converts"
  • Fensterressource hinzufügen: <cv:StringToColorConvert x:Key="bgCV"/>
  • Bindungsdatenkonvertierung: Background="{Binding} ElementName=txt,Path=Text,Converter={StaticResource bgCV}}"
<Window x:Class="WPF_Demo.MainWindow"
        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:local="clr-namespace:WPF_Demo"
        xmlns:cv="clr-namespace:WPF_Demo.Converts"  
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <Window.Resources>
        <cv:StringToColorConvert x:Key="bgCV"/>
    </Window.Resources>
    
    <StackPanel Margin="10">
        <TextBox x:Name="txt" Margin="10" Text="x-blue"/>
        <TextBlock Height="50" Margin="10" Background="{Binding ElementName=txt,Path=Text,Converter={StaticResource bgCV}}"/>
    </StackPanel>
</Window>

3. Einführung in das grundlegende Layout

Allgemeine zusätzliche Layoutattribute für untergeordnete Layoutelemente:

  • VerticalAlignment: Diese Eigenschaft wird verwendet, um die vertikalen Ausrichtungseigenschaften abzurufen oder festzulegen, die angewendet werden, wenn dieses Element in einem übergeordneten Element (z. B. einem Panel- oder Elementsteuerelement) kombiniert wird.
  • HorizontalAlignment: Diese Eigenschaft wird verwendet, um die horizontalen Ausrichtungseigenschaften abzurufen oder festzulegen, die angewendet werden, wenn dieses Element in einem übergeordneten Element (z. B. einem Panel- oder Elementsteuerelement) kombiniert wird.

1 StackPanel-Stapellayout

(1) Konzept: StackPanel ist ein Stapellayout, das seine untergeordneten Elemente in einer horizontalen oder vertikalen Reihe anordnet. StackPanel enthält eine Sammlung von UIElement-Objekten (eine Sammlung untergeordneter Elemente), die sich in der Eigenschaft Children befinden.

- Orientation : 获取或设置一个值,该值指示子元素的堆叠维度(方向),其中 Horizontal水平,Vertical垂直
- Children : 获取此Panel的 UIElementCollection 子元素集合(继承自 Panel)
- CanVerticallyScroll : 获取或设置一个值,该值指示内容能否垂直滚动。
- CanHorizontallyScroll : 获取或设置一个值,该值指示 StackPanel 能否水平滚动。
<Window x:Class="WpfTutorialSamples.Panels.StackPanel"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="StackPanel" Height="160" Width="300">
	<StackPanel Orientation="Horizontal">
		<Button VerticalAlignment="Top">Button 1</Button>
		<Button VerticalAlignment="Center">Button 2</Button>
		<Button VerticalAlignment="Bottom">Button 3</Button>
		<Button VerticalAlignment="Bottom">Button 4</Button>
		<Button VerticalAlignment="Center">Button 5</Button>
		<Button VerticalAlignment="Top">Button 6</Button>
	</StackPanel>
</Window>

(2) Scrollen: StackPanel bietet standardmäßig kein physisches Scrollen von Inhalten. Wenn physisches Scrollen anstelle von logischem Scrollen erforderlich ist, schließen Sie das StackPanel-Element bitte in ein ScrollViewer-Steuerelement ein und setzen Sie dessen CanContentScroll-Eigenschaft auf false.

2 Raster-Raster-Layout

(1) Konzept: Raster ist ein Rasterlayout, mit dem ein flexibler Rasterbereich definiert wird, der aus Spalten und Zeilen besteht. Grid enthält eine Sammlung von UIElement-Objekten (eine Sammlung untergeordneter Elemente), die sich in der Eigenschaft Children befinden. Untergeordnete Rasterelemente werden in der im Markup oder Code angezeigten Reihenfolge gezeichnet. , sodass eine hierarchische Anzeigereihenfolge (auch als Z-Reihenfolge bezeichnet) erreicht werden kann, wenn Elemente dieselben Koordinaten haben.

- Children : 获取此Panel的 UIElementCollection 子元素集合(继承自 Panel)
- ColumnDefinitions : 获取在 Grid 的实例上定义的 ColumnDefinitionCollection 列的定义信息集合
	- ColumnDefinition : 定义将应用于 Grid 元素的特定于列的属性,每个 ColumnDefinition 都成为表示最终网格布局中的列的占位符。
		- Width : 获取或设置 ColumnDefinition 定义的列的宽度值, GridLength 对象
			- 单位(Star) * : 占用剩余的空间按比例划分,宽度2*是1*的两倍
			- 单位(Auto) Auto : 该大小由内容对象元素的大小属性确定
			- 单位(Pixel) 像素绝对值 : 该值表示为一个绝对的像素值
- RowDefinitions : 获取在 Grid 的实例上定义的 RowDefinitionCollection 行的定义信息集合,
	- RowDefinition : 定义将应用于 Grid 元素的特定于行的属性, 每个 RowDefinition 都成为表示最终网格布局中的行的占位符。
		- Height : 获取或设置 RowDefinition 定义的行的高度值, GridLength 对象
			- 单位(Star) * : 占用剩余的空间按比例划分,宽度2*是1*的两倍
			- 单位(Auto) Auto : 该大小由内容对象元素的大小属性确定
			- 单位(Pixel) 像素绝对值 : 该值表示为一个绝对的像素值
- ShowGridLines : 获取或设置一个值,该值指示网格线在此 Grid 中是否可见

(2) Angehängtes Attribut (Attached): Ein angehängtes Attribut ist ein spezielles Abhängigkeitsattribut für eine Klasse, die das Attribut nicht definiert. Zum Beispiel „RowDefinition“, „ColumnDefinition“ des Rasterbereichs, „Links und rechts des Canvas-Bereichs“ usw.

- Column : 获取或设置一个值,该值表示 Grid 中的子内容所在的列,从0开始下同
- ColumnSpan : 获取或设置一个值,该值指示 Grid 中的子内容所跨越的总列数。默认1
- Row : 获取或设置一个值,该值表示 Grid 中的子内容所在的行
- RowSpan : 获取或设置一个值,该值表示在一个 Grid 中子内容所跨越的总行数。默认1
<Window x:Class="WpfTutorialSamples.Panels.GridColRowSpan"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GridColRowSpan" Height="110" Width="300">
	<Grid>
		<Grid.ColumnDefinitions>			
			<ColumnDefinition Width="1*" />
			<ColumnDefinition Width="1*" />
		</Grid.ColumnDefinitions>
		<Grid.RowDefinitions>
			<RowDefinition Height="*" />
			<RowDefinition Height="*" />
		</Grid.RowDefinitions>
		<Button>Button 1</Button>
		<Button Grid.Column="1">Button 2</Button>
		<Button Grid.Row="1" Grid.ColumnSpan="2">Button 3</Button>
	</Grid>
</Window>

3 Leinwand Leinwand

Canvas erbt von Controls.Panel und wird verwendet, um einen Bereich zu definieren, in dem untergeordnete Elemente explizit mithilfe von Koordinaten relativ zum Canvas- Bereich positioniert werden können . Die Eigenschaften von Canvas sind wie folgt:

(1) Der Standardwert der Eigenschaften „Höhe“ und „Breite“ von Canvas ist 0. Wenn Sie diese Werte nicht festlegen, wird die Leinwand nicht angezeigt, es sei denn, die Größe der untergeordneten Elemente wird automatisch geändert.
(2) Untergeordnete Elemente auf der Leinwand werden nie in der Größe geändert (wenn sich die Form ändert), sie werden nur an angegebenen Koordinaten platziert. Wenn Sie untergeordnete Inhalte automatisch anpassen und ausrichten möchten, verwenden Sie am besten das Rasterelement .
(3) Die vertikale und horizontale Ausrichtung bei untergeordneten Elementen funktioniert nicht. Untergeordnete Elemente werden nur an Positionen platziert, die durch die Canvas-Eigenschaften „Links“, „Oben“, „Rechts“ und „Unten“ festgelegt werden.
(4) Positionspriorität: Wenn die Left-Eigenschaft des Canvas festgelegt ist, hat die Right-Eigenschaft keine Auswirkung. Wenn die Top-Eigenschaft des Canvas festgelegt ist, hat die Bottom-Eigenschaft keine Auswirkung.

- 属性:
	- Children : 获取此Panel的 UIElementCollection 子元素集合(继承自 Panel)
	- Width: 获取或设置元素的宽度。(继承自 FrameworkElement)
	- Height: 获取或设置元素的建议高度。(继承自 FrameworkElement)
- 附加属性:
	- Bottom:获取或设置一个值,该值表示元素底部与其父 Canvas 底部之间的相对距离。(单位是像素)
	- Left:获取或设置一个值,该值表示元素左侧与其父 Canvas 左侧之间的距离。
	- Right:获取或设置一个值,该值表示元素右侧与其父 Canvas 右侧之间的距离。
	- Top:获取或设置一个值,该值表示元素顶部与其父 Canvas 顶部之间的距离。
	- Panel.ZIndex:获取或设置一个值,该值表示元素在 Z 平面中的显示顺序(上下深度顺序/层叠顺序)
		- ZIndex值越大显示优先级越高,允许负值,ZIndex的最大值为32766,默认值为0)。
		- 相同ZIndex则按照绘制/添加顺序,依次覆盖显示
<!--Canvas实例:XAML版本-->
<Window x:Class="WPF_Demo.MainWindow"
        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:local="clr-namespace:WPF_Demo"
        xmlns:vm="clr-namespace:WPF_Demo.Status"
        xmlns:cm="clr-namespace:WPF_Demo.Commands"
        mc:Ignorable="d" 
        Title="MainWindow" Height="275" Width="260">
    <Canvas>
        <Ellipse Fill="Gainsboro"  Canvas.Left="25" Canvas.Top="25" Width="200" Height="200" />
        <Rectangle Fill="LightBlue" Panel.ZIndex="1" Canvas.Left="25" Canvas.Top="25" Width="50" Height="50" />
        <Rectangle Fill="LightCoral" Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" />
        <Rectangle Fill="LightCyan" Panel.ZIndex="2" Canvas.Left="75" Canvas.Top="75" Width="50" Height="50" />
    </Canvas>
</Window>
//Canvas实例:代码版本
namespace WPF_Demo
{
    
    
    public partial class MainWindow : Window
    {
    
    
        public MainWindow()
        {
    
    
            InitializeComponent();
            //1.添加Ellipse对象
            Ellipse ellipse = new Ellipse();
            ellipse.Fill = new SolidColorBrush(Colors.Gainsboro);
            ellipse.Width = 200;
            ellipse.Height = 200;
            //Set Canvas position  
            Canvas.SetLeft(ellipse, 25);
            Canvas.SetTop(ellipse, 25);
            //Add Ellips to Canvas 
            this.canvas.Children.Add(ellipse);

            //2.添加Rectangle对象1
            Rectangle Red_rectangle = new Rectangle();
            Red_rectangle.Fill = new SolidColorBrush(Colors.Red);
            Red_rectangle.Width = 50;
            Red_rectangle.Height = 50;
            //Set Canvas position  
            Canvas.SetLeft(Red_rectangle, 25);
            Canvas.SetTop(Red_rectangle, 25);
            Panel.SetZIndex(Red_rectangle, 1);
            //Add Ellips to Canvas 
            this.canvas.Children.Add(Red_rectangle);
            
            //3.添加Rectangle对象2
            Rectangle Green_rectangle = new Rectangle();
            Green_rectangle.Fill = new SolidColorBrush(Colors.Green);
            Green_rectangle.Width = 50;
            Green_rectangle.Height = 50;
            //Set Canvas position  
            Canvas.SetLeft(Green_rectangle, 50);
            Canvas.SetTop(Green_rectangle, 50);
            //Add Ellips to Canvas 
            this.canvas.Children.Add(Green_rectangle);

            //4.添加Rectangle对象3
            Rectangle Yello_rectangle = new Rectangle();
            Yello_rectangle.Fill = new SolidColorBrush(Colors.Yellow);
            Yello_rectangle.Width = 50;
            Yello_rectangle.Height = 50;
            //Set Canvas position  
            Canvas.SetLeft(Yello_rectangle, 75);
            Canvas.SetTop(Yello_rectangle, 75);
            Panel.SetZIndex(Yello_rectangle, 2);
            //Add Ellips to Canvas 
            this.canvas.Children.Add(Yello_rectangle);
        }
    }

}

Ich denke du magst

Origin blog.csdn.net/qq_40772692/article/details/126426982
Empfohlen
Rangfolge