【发布时间】:2018-05-16 11:01:02
【问题描述】:
所以在这一点上我很困惑。我现在绑定它的方式非常完美,但我想使用多个类进行数据绑定。所以我现在所拥有的(工作版本)是这样的。在我的 MainWindow 中,我将 DataContext 设置为我的类的一个新实例,名为 Server
public MainWindow()
{
InitializeComponent();
DataContext = server;
}
我已经将一些属性绑定到几个控件,像这样
<ScrollViewer VerticalScrollBarVisibility="Visible" Name="Scroller" Margin="266,95,10,192" Background="#1f1f1f">
<StackPanel>
<ItemsControl ItemsSource="{Binding ConsoleOutput, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}"
Foreground="{Binding Foreground}"
Name="SavedBlocks" FontFamily="Consolas"
LayoutUpdated="SavedBlocks_LayoutUpdated" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
这就是我的Server 课程
public class Server : INotifyPropertyChanged
{
public string consoleInput = string.Empty;
public ObservableCollection<Message> consoleOutput = new ObservableCollection<Message>();
public Server()
{
}
public string ConsoleInput
{
get => consoleInput;
set
{
consoleInput = value;
OnPropertyChanged("ConsoleInput");
}
}
private void OKDataReceived(object sender, DataReceivedEventArgs e)
{
if (ServerIsRunning)
{
if (!string.IsNullOrEmpty(e.Data))
Application.Current.Dispatcher.Invoke(() =>
{
if (e.Data.Contains("ERROR"))
{
ConsoleOutput.Add(new Message { Text = e.Data, Foreground = ERRORBrush });
ConsoleInput = string.Empty;
return;
}
if (e.Data.Contains("WARN"))
{
ConsoleOutput.Add(new Message { Text = e.Data, Foreground = WARNINGBrush });
ConsoleInput = string.Empty;
return;
}
ConsoleOutput.Add(new Message { Text = e.Data, Foreground = OKBrush });
ConsoleInput = string.Empty;
});
}
}
public ObservableCollection<Message> ConsoleOutput
{
get => consoleOutput;
set
{
consoleOutput = value;
OnPropertyChanged("ConsoleOutput");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (null != PropertyChanged)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
如您所见,ObservableCollection 具有 Message 类型,即此类
public class Message : INotifyPropertyChanged
{
public Message()
{
_foreground = Brushes.Green;
}
private string _text;
public string Text
{
get { return _text; }
set { _text = value; OnPropertyChanged("Text"); }
}
private Brush _foreground;
public Brush Foreground
{
get { return _foreground; }
set
{
_foreground = value;
OnPropertyChanged("Foreground");
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
if (null != PropertyChanged)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
我遇到的问题是当我尝试创建一个 MasterViewModel 类时,该类将包含所有其他类的属性
public class MasterViewModel
{
public Server ServerViewModel { get; } = new Server();
public Player PlayerViewModel { get; } = new Player();
public Message MessageViewModel { get; } = new Message();
}
然后我要设置属性如下
以及更改 DataContext
public MainWindow()
{
InitializeComponent();
DataContext = new MasterViewModel();
}
XAML
<ItemsControl ItemsSource="{Binding ServerViewModel.ConsoleOutput, Mode=OneWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MessageViewModel.Text}"
Foreground="{Binding MessageViewModel.Foreground}"
Name="SavedBlocks" FontFamily="Consolas"
LayoutUpdated="SavedBlocks_LayoutUpdated" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
但是突然间它停止了工作,它不会通知 UI 并且 UI 根本不会更新。 我在这里错过了一些小东西吗?因为我一辈子都找不到这里的问题。
新绑定
static Server server = new Server();
static Player player = new Player();
static Message message = new Message();
public MainWindow()
{
InitializeComponent();
DataContext = new MasterViewModel()
{
ServerViewModel = server,
PlayerViewModel = player,
MessageViewModel = message,
};
}
【问题讨论】:
-
ItemsControl 中项目容器的 DataContext(以及因此 DataTemplate 中的所有元素)自动设置为相应的项目对象,即 ItemsSource 集合中的相应元素。这意味着 DataTemplate 中 TextBlock 的 DataContext 已经包含一个 Message 对象。然后你绑定它的属性,例如
Text="{Binding Text}". -
我尝试再次恢复它们,只是更改了 DataContext 但似乎没有任何改变
-
为什么以及在哪里“更改 DataContext”?这似乎没有意义。
-
应该的。你一定做错了什么。请注意,在 ItemsSource Binding 上设置
Mode=OneWay是多余的。 -
您查看的服务器实例可能与 MasterViewModel 的 ServerViewModel 属性中的实例不同。您的代码中似乎有一个
server变量。将其分配给 ServerViewModel 属性。
标签: c# .net wpf mvvm data-binding