主界面

<Window x:Class="MyWPFSimple2.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:MyWPFSimple2"
        mc:Ignorable="d" WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="460" Width="500">
    
    <Window.DataContext>
        <local:VMMainWindow/>
    </Window.DataContext>
    <Window.Resources>
        <ResourceDictionary Source="PersonInfoDTmpl.xaml"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <GroupBox Header="绑定 DataContext">
                <local:PersonInfo/>
            </GroupBox>
            <Button x:Name="btnShow" Click="btnShow_Click" Content="显示信息" Margin="0 5 0 0"/>
            <GroupBox Header="散装">
                <StackPanel HorizontalAlignment="Center" Margin="5">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="姓名:" VerticalAlignment="Center"/>
                        <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center" Text="{Binding Name}"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
                        <TextBlock Text="年龄:" VerticalAlignment="Center"/>
                        <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center" Text="{Binding Age}" />
                    </StackPanel>
                </StackPanel>
            </GroupBox>
            <GroupBox Header="数据模板" HorizontalAlignment="Center" Margin="5">
                <ContentControl ContentTemplate="{StaticResource DPersonInfoTmpl}" Content="{Binding}"/>
            </GroupBox>
            <GroupBox Header="绑定自己">
                <local:PersonInfoTest PersonName="{Binding Name}" PersonAge="{Binding Age}"/>
            </GroupBox>
        </StackPanel>
    </Grid>
</Window>

BehindCode:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyWPFSimple2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            m_VMMainWindow = DataContext as VMMainWindow;
        }

        private VMMainWindow m_VMMainWindow;
        private void btnShow_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("姓名:" + m_VMMainWindow.Name + "\r\n" + "年龄:" + m_VMMainWindow.Age, "信息");
        }
    }


    public class VMMainWindow : ObservableObject
    {
        public VMMainWindow()
        {
            Name = "令狐冲";
            Age = 25;
        }
        private string m_Name;
        public string Name
        {
            get { return m_Name; }
            set
            {
                m_Name = value;
                RaisePropertyChanged(nameof(Name));
            }
        }

        private int m_Age;
        public int Age
        {
            get { return m_Age; }
            set
            {
                m_Age = value;
                RaisePropertyChanged(nameof(Age));
            }
        }
    }
}

绑定 Window 的 DataContext

PersonInfo.xaml 控件

<UserControl x:Class="MyWPFSimple2.PersonInfo"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyWPFSimple2" 
             mc:Ignorable="d"  Background="LightBlue"
             d:DesignHeight="70" d:DesignWidth="200"
             DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext}"
             >
    
    <UserControl.Resources>
        <local:PerAgeConvert x:Key="agg_add_one"/>
        <local:PersonNameConvert x:Key="name_with_sub"/>
    </UserControl.Resources>

    <Grid>
        <StackPanel HorizontalAlignment="Center" Margin="5">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="姓名:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center"
                         Text="{Binding Name, Converter={StaticResource name_with_sub}}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
                <TextBlock Text="年龄:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center" 
                         Text="{Binding Age, Converter={StaticResource agg_add_one}}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>

BehindCode:

这种方式,没有 behindcode。

namespace MyWPFSimple2
{
    /// <summary>
    /// PersonInfo.xaml 的交互逻辑
    /// </summary>
    public partial class PersonInfo : UserControl
    {
        public PersonInfo()
        {
            InitializeComponent();
        }
    }     
}

散装

散装的就不说了。

数据模板 DataTemplate

这个也是直接找的 DataContext 绑定。

PersonInfoDTmpl.xaml

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

    <local:PerAgeConvert x:Key="agg_add_one"/>
    <local:PersonNameConvert x:Key="name_with_sub"/>

    <DataTemplate x:Key="DPersonInfoTmpl">
        <StackPanel HorizontalAlignment="Center" Margin="5">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="姓名:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center"
                         Text="{Binding Name}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
                <TextBlock Text="年龄:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center" 
                         Text="{Binding Age}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>

</ResourceDictionary>

自定义依赖属性

这种方式,没有测试成功。 ViewModel 更改能通知到它,但它自己更改没有通知到 VM,有时间更熟悉WPF后再测试一下。

主界面绑定的是 clr 属性,而 UserControl 绑定的是 Property 属性, UserControl Property 更改的时候没有通知到 clr 属性,没能实现双向绑定。

PersonInfoTest.xaml

<UserControl x:Class="MyWPFSimple2.PersonInfoTest"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyWPFSimple2" 
             mc:Ignorable="d"  Background="LightPink"
             d:DesignHeight="70" d:DesignWidth="200"
            >

    <UserControl.Resources>
        <local:PerAgeConvert x:Key="agg_add_one"/>
        <local:PersonNameConvert x:Key="name_with_sub"/>
    </UserControl.Resources>

    <Grid>
        <StackPanel HorizontalAlignment="Center" Margin="5">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="姓名:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center"
                       Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=PersonName, Mode=TwoWay}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0 2 0 0">
                <TextBlock Text="年龄:" VerticalAlignment="Center"/>
                <TextBox BorderBrush="Black" Height="30" Width="150" VerticalContentAlignment="Center" 
                         Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=PersonAge, Mode=TwoWay}"/>
            </StackPanel>
        </StackPanel>
    </Grid>

</UserControl>

BehindCode:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MyWPFSimple2
{
    /// <summary>
    /// PersonInfoTest.xaml 的交互逻辑
    /// </summary>
    public partial class PersonInfoTest : UserControl, INotifyPropertyChanged
    {
        public PersonInfoTest()
        {
            InitializeComponent();
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(PersonInfoTest), new FrameworkPropertyMetadata(typeof(PersonInfoTest)));
        }

        public string PersonName
        {
            get
            {
                return (string)GetValue(PersonNameProperty);
            }
            set
            {
                SetValue(PersonNameProperty, value);
                RaisePropertyChanged(nameof(PersonName));
            }
        }

        // Using a DependencyProperty as the backing store for PersonName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PersonNameProperty =
            DependencyProperty.Register("PersonName", typeof(string), typeof(PersonInfoTest), new PropertyMetadata("悟空"));

        public int PersonAge
        {
            get
            {
                return (int)GetValue(PerAgeProperty);
            }
            set
            {
                SetValue(PerAgeProperty, value);
                RaisePropertyChanged(nameof(PersonAge));
            }
        }

        // Using a DependencyProperty as the backing store for PerAge.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PerAgeProperty =
            DependencyProperty.Register("PersonAge", typeof(int), typeof(PersonInfoTest), new PropertyMetadata(0));

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Convert.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace MyWPFSimple2
{
    public sealed class PersonNameConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string name = (string)value;
            return name + " 先生/女生";
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string val = (string)value;
            return val.Split(' ')[0];
        }
    }

    public sealed class PerAgeConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int val = (int)value;
            return val + 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int val = int.Parse((string)value);
            return val - 1;
        }
    }
}

原文地址:http://www.cnblogs.com/huvjie/p/16909290.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性