Tob*_*lls 8 c# wpf xaml binding mvvm
我正在重新编写我的Windows表单项目,该项目为羊剪切事件(不要问,这是新西兰的一项大型运动)从vbnet到wpf c#进行评分,并且遇到了一个我似乎无法克服的问题.
我有两个窗户.一个是您输入内容的源窗口(如当前事件名称),另一个窗口将以闪存方式显示此信息,以便投影到屏幕上(因此将在第二个监视器上)以及其他一些数据在via XML over the network.我将它设置为MVVM,将ViewModel和Model作为单独的项目.
在我的主窗口上,我可以很好地绑定控件,如果我输入一个文本框,它会立即出现在另一个文本框中,如果它绑定到同一个东西.但是,在第二个窗口中,我将控件绑定到同一个窗口,并且它没有更新.
我已经围绕这个问题进行了一个星期的讨论,网上的每个例子都显示了如何在一个窗口上进行操作,我已经工作正常,但是缺少两个窗口示例.
这是我的......
这是在我的ViewModel项目中
namespace SheepViewModel
{
public class SheepViewModel : INotifyPropertyChanged
{
private string _CurrentEventName;
static SheepViewModel _details;
public string CurrentEventName
{
get { return _CurrentEventName; }
set
{
_CurrentEventName = value;
OnPropertyChanged("CurrentEventName");
}
}
public static SheepViewModel GetDetails()
{
if (_details == null)
_details = new SheepViewModel();
return _details;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
Console.WriteLine("Test");
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个主窗口,没有真正的代码,除了一行打开第二个窗口,我们将...
public MainWindow()
{
ScoreScreen SW = new ScoreScreen();
SW.Show();
InitializeComponent();
}
Run Code Online (Sandbox Code Playgroud)
然后是XAML
<Window x:Class="Sheep_Score_3._1.MainWindow"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
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:vm="clr-namespace:SheepViewModel;assembly=SheepViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="433.689" Width="941.194">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
<Window.Resources>
<Grid Margin="0,0,0,0">
<TextBox x:Name="CurrentEventName" Height="23" Margin="131.01,163.013,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" Width="327.151" Text="{Binding CurrentEventName, Mode=TwoWay}"/>
<TextBox Text="{Binding CurrentEventName, Mode=TwoWay}" Margin="39.605,0,0,108.567" Height="49.111" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="399" />
</Grid>
Run Code Online (Sandbox Code Playgroud)
上面的代码都可以正常工作,如果我在第一个文本框中键入它出现在第二个文本框中的文本.如果我在通知部分放置一个console.writeline,那么我可以看到它击中并更新.
现在我添加第二个窗口,设置完全相同...
<Window x:Class="Sheep_Score_3._1.ScoreScreen"
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:vm="clr-namespace:SheepViewModel;assembly=SheepViewModel"
mc:Ignorable="d"
Title="ScoreScreen" Height="300" Width="300">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
<Grid>
<TextBox x:Name="textBlock" HorizontalAlignment="Left" Margin="79.374,116.672,0,0" TextWrapping="Wrap" Text="{Binding CurrentEventName, Mode=TwoWay}" VerticalAlignment="Top"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)
同样,这里没有真正的代码.
奇怪的是,如果我以两种方式进行此控制并输入它,我可以看到它击中相同的通知部分,但它没有更新其他窗口.
我不确定我在这里缺少什么,所以任何指导我正确方向的帮助将非常感激.
小智 11
那是因为两个窗口必须共享ViewModel的完全相同的实例.
您的所有属性都是实例属性,例如
public string CurrentEventName { get { // snip
Run Code Online (Sandbox Code Playgroud)
因此,所有值都与每个实例不同.您正在创建两个实例,每个窗口一个.
<Window x:Class="Sheep_Score_3._1.MainWindow"
xmlns:blah="http://inurxamlskippinurschemas.org">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
Run Code Online (Sandbox Code Playgroud)
那是一个例子,这是另一个例子
<Window x:Class="Sheep_Score_3._1.ScoreScreen"
xmlns:blah="http://yaddayaddawhocares.derp">
<Window.DataContext>
<vm:SheepViewModel/>
</Window.DataContext>
Run Code Online (Sandbox Code Playgroud)
请记住,xaml只是被反序列化为对象图的标记.您有两个不同的标记文件,它们包含其中描述的所有内容的不同实例.
这没有什么不对,使用具有实例属性的视图模型没有任何问题.事实上,这是使用静态和静态绑定的首选方式.
答案很幸运.您需要将两个窗口都放在视图模型的同一个实例中.
首先,删除<Window.DataContext>两个窗口中的所有废话.那不适合你.现在,只需将构造函数更改为
public MainWindow()
{
var viewModel = new SheepViewModel();
ScoreScreen SW = new ScoreScreen();
SW.DataContext = viewModel;
SW.Show();
InitializeComponent();
//NOTICE! After Init is called!
DataContext = viewModel;
}
Run Code Online (Sandbox Code Playgroud)
而且你已经完成了.
| 归档时间: |
|
| 查看次数: |
3279 次 |
| 最近记录: |