从c#中单独的类绑定wpf中的文本框
本文关键字:wpf 文本 绑定 单独 | 更新日期: 2023-09-27 18:05:19
新的WPF尝试实现一个简单的文本框绑定。需要一些帮助才能使它运行。
XAML
<Window x:Class="WPFModel.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:src="clr-namespace:WPFModel"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<src:Test x:Key="myDataSource" TextBoxName="Text Init" />
</Window.Resources>
<Grid>
<TextBox x:Name="S1" Text = "{Binding Source={StaticResource myDataSource}, Path=TextBoxName, UpdateSourceTrigger= PropertyChanged, Mode = TwoWay}" HorizontalAlignment="Left" Height="50" Margin="160,165,0,0" VerticalAlignment="Top" Width="185"/>
</Grid>
主窗口namespace WPFModel
{
public partial class MainWindow : Window
{
Test tb = new Test();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
tb.Drawtext();
}
}
}
代码后面
namespace WPFModel
{
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string value1;
public string TextBoxName
{
get { return value1; }
set
{
value1 = value;
RaisePropertyChanged("TextBoxName");
}
}
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public void Drawtext()
{
TextBoxName = "Textbox text";
}
}
}
您将Window的数据上下文设置为自身,而不是将其设置为Test
对象的实例:
this.DataContext = tb;
然后你可以将文本框的绑定设置为数据上下文对象的属性:
... Text="{Binding TextBoxName, UpdateSourceTrigger= PropertyChanged, Mode = TwoWay}" ...
您设置了多次DataContext。一次在窗口(DataContext="{Binding RelativeSource={RelativeSource Self}}"
)的属性中的XAML标记中,一次在窗口(this.DataContext = this;
)的代码后置构造函数中。在这两种情况下,您都没有将DataContext设置为Test
的实例。
您还创建了Test
的两个实例。一次在作为资源的XAML标记中(<src:Test x:Key="myDataSource" TextBoxName="Text Init" />
),另一次在代码隐藏中(Test tb = new Test();
)。然后将文本框绑定到Test
的资源实例。由于您在代码隐藏实例上调用DrawText()
,窗口中的文本框永远不会更新。
相反,你想做的是有一个Test
的实例作为你的窗口的DataContext。由于理想情况下,我们希望在MVVM中保持代码隐藏文件(您正在调用主窗口)中的代码量最少,因此最好的方法是如下面的示例所示。你还会看到你可以使用Commands而不是OnClick处理程序来调用视图模型中的操作。如果您不熟悉RelayCommand
,那么请查看这里的简单实现
XAML
<Window x:Class="WPFModel.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:src="clr-namespace:WPFModel"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<src:Test />
</Window.DataContext>
<StackPanel>
<TextBox x:Name="S1" Text = "{Binding TextBoxName}" HorizontalAlignment="Left" Height="50" Margin="160,165,0,0" VerticalAlignment="Top" Width="185"/>
<Button Content="Click Me!" Command={Binding DrawTextCommand} />
</StackPanel>
</Window>
namespace WPFModel
{
public class Test : INotifyPropertyChanged
{
public ICommand DrawTextCommand { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
private string value1;
public string TextBoxName
{
get { return value1; }
set
{
value1 = value;
RaisePropertyChanged("TextBoxName");
}
}
public Test()
{
this.DrawTextCommand = new RelayCommand(DrawText);
}
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public void Drawtext()
{
TextBoxName = "Textbox text";
}
}
}
主窗口代码隐藏
namespace WPFModel
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}