Member 12658724 Ответов: 2

Повторное использование xaml для проекта WPF


У меня есть модальный контроль использования. Он будет использоваться во многих местах. Другая часть-это часть сообщения.

Я не знаю, как сделать его повторно полезным.
<Grid Margin="10">
                <Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
                        <StackPanel Margin="10">
                                <TextBlock Text="{Binding Message}" />
                        </StackPanel>
                </Border>
</Grid>

Нужен код, а не концептуальные утверждения.

Что я уже пробовал:

Пытался использовать шаблон содержимого или datatemplate. Просто не знаю, как это применить.

Graeme_Grant

"Пытался использовать шаблон содержимого или datatemplate. Просто не знаю, как это применить." -
Эта ссылка может помочь: Создание и использование словарей ресурсов в WPF и Silverlight – WPF & Silverlight Designer[^]

2 Ответов

Рейтинг:
15

Graeme_Grant

Вот шаги, чтобы сделать то, что вы просите:

1. в обозревателе решений щелкните правой кнопкой мыши на вашем решении > Добавить > Новый проект & выберите "Библиотека WPF UserControl (.Net Framework), дайте ей имя и нажмите кнопку ОК.

2. Теперь добавьте элемент управления UserControl с заданным именем. Довольно его с Xaml и добавить функциональность с кодом, а затем скомпилировать.

3. добавьте ссылку в проект, который хочет ее использовать.

4. Затем в Xaml добавьте ссылку на пространство имен UserControl в новую внешнюю библиотеку UserControl

5. Добавление пользовательского элемента управления в XAML-код.

Если вы хотите увидеть, как это делается с кодом, то взгляните на эту статью: Гибкий WPF ToggleSwitch Lookless Control в C# & VB[^] - не UserControl, но применяется тот же принцип (как описано выше).

ОБНОВЛЕНИЕ Бросил это вместе во время обеда:

1. UserControlLib для хранения наших общих пользовательских элементов управления. Вот ваш UserControl называется MySharedUserControl:

<UserControl

    x:Class="UserControlLib.MySharedUserControl"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid Margin="10">
        <Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
            <StackPanel Margin="10">
                <TextBlock Text="{Binding Message}" />
            </StackPanel>
        </Border>
    </Grid>

</UserControl>


2. наше тестовое приложение WpfApp1 со ссылкой, добавленной к нашему UserControlLib Элемент управления UserControl Либ:

Код-зад для главного окна:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private string message;
        public string Message
        {
            get { return message; }
            set
            {
                message = value;
                RaisePropertyChanged();
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Message = "Test Message";
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

И в XAML:
<Window

    x:Class="WpfApp1.MainWindow"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:MyLib="clr-namespace:UserControlLib;assembly=UserControlLib"

    Title="MainWindow" Height="350" Width="525">

    <Grid>
        <Button Content="Show Message" Click="Button_Click"

                VerticalAlignment="Top" HorizontalAlignment="Center"

                Margin="20" Padding="10 5"/>

        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="MESSAGE:" Margin="0 0 10 0" VerticalAlignment="Center"/>
            <MyLib:MySharedUserControl Width="200" Grid.Column="1"/>
        </Grid>
    </Grid>

</Window>

Наш элемент управления UserControl lib и контроля пространства имен добавляется к заголовку: xmlns:MyLib="clr-namespace:UserControlLib;assembly=UserControlLib" и этот элемент управления используется с нашим пространством имен: <MyLib:MySharedUserControl Width="200" Grid.Column="1"/>


Рейтинг:
1

PureNsanity

Я бы не стал использовать здесь шаблон. Шаблоны предназначены для переопределения или предоставления элементов пользовательского интерфейса, но если все, что меняется, - это содержимое сообщения, вам просто нужна открытая привязка.

В вашем коде позади сделайте это:

public partial class MyReusedView : UserControl
{
    public static DependencyProperty MessageProperty = DependencyProperty.Register("Message", typeof(string), typeof(MyReusedView));

    public string Message
    {
        get { return (string)GetValue(MessageProperty); }

        set { SetValue(MessageProperty, value); }
    }

    public MyReusedView()
    {
        InitializeComponent();

        DataContext = this;
    }
}

Тогда все, что вам нужно в XAML, это:
<common:MyReusedView Message={Binding MyMessageSource.Message}/>

Как бы подразумевается пространством имен, просто убедитесь, что класс находится на достаточно высоком уровне, чтобы вы могли соответствующим образом ссылаться на него в других сборках.

Если ваш модальный элемент управления уже имеет модель представления в качестве DataContext, то вы можете использовать ее в конструкторе:
public MyReusedView()
{
    InitializeComponent();

    DataContext = new MyReusedViewModel();

    Binding messageBinding = new Binding("Message");
    messageBinding.Source = DataContext;
    messageBinding.Mode = BindingMode.OneWayToSource;
    SetBinding(MyReusedView.MessageProperty, messageBinding);
}

Таким образом, вы можете сохранить любую другую логику в модели представления и просто предоставить свойство через представление, чтобы к нему можно было получить доступ через XAML.