重用xaml用于WPF项目 [英] Reuse xaml for WPF project

查看:122
本文介绍了重用xaml用于WPF项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模态使用控件。它将在很多地方使用。不同的部分是消息部分。



我不知道如何让它重复使用。

 <网格边距=10> 
< Border Background =GhostWhiteBorderBrush =GainsboroBorderThickness =1>
< StackPanel Margin =10>
< TextBlock Text ={Binding Message}/>
< / StackPanel>
< / Border>
< / Grid>



需要代码而不是概念陈述。



我尝试过:



尝试使用内容模板或datatemplate。只是不知道如何应用它。

解决方案

以下是执行您所要求的步骤:



1.在解决方案资源管理器中,右键单击解决方案>添加>新项目&选择WPF UserControl Library(.Net Framework),给它起一个名字,然后单击OK按钮。



2.现在添加一个具有给定名称的UserControl。使用Xaml并添加代码然后编译功能。



3.在项目中添加一个想要使用它的引用。



4.然后在您的Xaml中,在新的外部UserControl库中为UserControl添加一个Namespace引用



5.将UserControl添加到你的Xaml。



如果你想看看代码是如何完成的,那么看看这篇文章: C#& VB中灵活的WPF ToggleSwitch无视控制 [ ^ ] - 不是UserControl,但同样的原则(如上所述)适用。



UPDATE 在h时将它们放在一起午餐:



1. UserControlLib 来保存我们共享的UserControls。这是您的UserControl,名为 MySharedUserControl

 <   UserControl   

x:Class = UserControlLib.MySharedUserControl

xmlns = http://schemas.microsoft.com/winfx/2006 / xaml / presentation
< span class =code-attribute>
xmlns:x = http://schemas.microsoft.com/winfx/2006/xaml >

< 网格 保证金 = 10 >
< Border 背景 = GhostWhite BorderBrush = Gainsboro BorderThickness = 1 < span class =code-keyword>>
< StackPanel 保证金 = 10 >
< TextBlock 文本 = {Binding Message} / >
< / StackPanel >
< / Border >
< / Grid >

< / UserControl >





2.我们的测试应用 WpfApp1 ,并在 UserControlLib UserControl lib:



MainWindow的代码隐藏:

 使用 System.ComponentModel; 
使用 System.Runtime.CompilerServices;
使用 System.Windows;

命名空间 WpfApp1
{
public partial class MainWindow:Window,INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this ;
}

private string 消息;
public string 消息
{
获取 {返回消息; }
set
{
message = value ;
RaisePropertyChanged();
}
}

私人 void Button_Click( object sender,RoutedEventArgs e)
{
Message = 测试消息;
}

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



和Xaml:

 <  窗口  
< span class =code-attribute>
x:Class = WpfApp1.MainWindow

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

xmlns:x = http://schemas.microsoft.com/winfx/2006/xaml
< span class =code-attribute>
xmlns:MyLib = clr-namespace:UserControlLib; assembly = UserControlLib

Title = MainWindow < span class =code-attribute>高度 = 350 宽度 = 525 >

< 网格 >
< 按钮 内容 = 显示消息 点击 = Button_Click

VerticalAlignment = Top Horizo​​ntalAlignment = 中心

保证金 = 20 填充 = 10 5 / >

< span class =code-keyword><
Grid Horizo​​ntalAlignment = 中心 VerticalAlignment = 中心 >
< 网格。 ColumnDefinitions >
< ColumnDefinition 宽度 = 自动 / >
< ColumnDefinition / >
< / Grid.ColumnDefinitions >
< TextBlock 文本 = 消息: 保证金 = 0 0 10 0 VerticalAlignment = 中心 / >
< MyLib:MySharedUserControl 宽度 = 200 Grid.Column = 1 / < span class =code-keyword>>
< / Grid >
< / Grid >

< / Window >



我们的UserControl Lib和控件NameSpace被添加到标题: xmlns:MyLib =clr-namespace:UserControlLib; assembly = UserControlLib和该控件与我们的NameSpace一起使用:< MyLib:MySharedUserControl Width =200Grid.Column =1/>


< blockquote>我不会在这里使用模板。模板旨在覆盖或提供UI元素,但如果所有更改的内容都是消息内容,则只需要一个公开的绑定。



在您的代码中执行此操作:

公共部分类MyReusedView:UserControl 
{
public static DependencyProperty MessageProperty = DependencyProperty.Register(Message,typeof(string),typeof(MyReusedView) ));

public string消息
{
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();

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



这样你就可以在视图模型中保留任何其他逻辑,只需通过视图公开属性,就可以通过XAML访问它。

I have a modal use control. It will be used in many places. The different part is the message part.

I am not sure how to make it re-useful.

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


Need code rather than concept statements.

What I have tried:

Tried to use content template or datatemplate. Just don't know how to apply it.

解决方案

Here are the steps to do what you ask:

1. In the Solution Explorer, right-click on your solution > Add > New Project & select "WPF UserControl Library (.Net Framework), give it a name and click on the OK button.

2. Now Add a UserControl with a given name. Pretty it up with Xaml and add functionality with code then compile.

3. Add a reference in the project that wants to use it.

4. Then in your Xaml, add a Namespace reference to the UserControl in your new external UserControl library

5. Add the UserControl to your Xaml.

If you want to see how it is done with code, then have a look at this article: Flexible WPF ToggleSwitch Lookless Control in C# & VB[^] - not a UserControl but same principle (as described above) applies.

UPDATE Threw this together whilst having lunch:

1. UserControlLib to hold our shared UserControls. Here is your UserControl called 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. Our test App WpfApp1 with a reference added to our UserControlLib UserControl lib:

Code-Behind for the MainWindow:

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));
        }
    }
}


And the 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>


Our UserControl Lib and the control NameSpace is added to the header: xmlns:MyLib="clr-namespace:UserControlLib;assembly=UserControlLib" and the control is used with our NameSpace: <MyLib:MySharedUserControl Width="200" Grid.Column="1"/>


I wouldn't use a template here. Templates are meant to override or provide the UI elements, but if all that's changing is the message content you simply need an exposed binding.

In your code behind do this:

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;
    }
}


Then all you need in XAML is:

<common:MyReusedView Message={Binding MyMessageSource.Message}/>


As kind of implied by the namespace, just make sure to put the class at a high enough level so you can reference it appropriately in other assemblies.

If your modal control has a view model as the DataContext already, then you can use this in the constructor:

public MyReusedView()
{
    InitializeComponent();

    DataContext = new MyReusedViewModel();

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


Such that you can keep any other logic in the view model and just expose the property through the view so it can be accessed via XAML.


这篇关于重用xaml用于WPF项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆