主界面
<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;
}
}
}
标签:控件,自定义,C#,object,System,value,Windows,using,public
From: https://www.cnblogs.com/huvjie/p/16909290.html