- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在用单个窗口中的 TabControl 编写 WPF 桌面应用程序。我在 XAML View 中对一些属性进行了数据绑定(bind),只要在 .cs 文件的构造函数中更改了值,它就可以正常工作。稍后所做的更改不会显示在 View 中。
我有 4 个文件(实际上做的事情):MainWindow.xaml(显示 TabControl + 一些按钮):
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<SystemGesture:Double x:Key="FontSize">14</SystemGesture:Double>
<SystemGesture:Double x:Key="ImageSize">26</SystemGesture:Double>
<SystemGesture:Double x:Key="MenuButtonSize">30</SystemGesture:Double>
<DataTemplate DataType="{x:Type local:ViewModelBooks}">
<local:ViewBooks/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelFiles}">
<local:ViewFiles/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelMusic}">
<local:ViewMusic />
</DataTemplate>
</Window.Resources>
<TabControl x:Name="TabControlMain" TabStripPlacement="Left"
ItemsSource="{Binding Screens}"
Background="{DynamicResource BackgroundLight}"
SelectedItem="{Binding SelectedItem}"
>
MainWindowViewModel.cs(选择要显示的屏幕并将菜单命令委托(delegate)给 ViewModelBooks 对象):
namespace Bla{
public class MainWindowViewModel {
public MainWindowViewModel() {
MenuCommand = new RelayCommand(o => {
Debug.WriteLine("Menu Command " + o);
SwitchBooks(o);
});
SelectedItem = "Bla.ViewModelBooks";
}
private object _selectedItem;
public object SelectedItem {
get {
return _selectedItem;
}
set {
_selectedItem = value;
}
}
object[] _screens = new object[] { new ViewModelBooks(), new ViewModelMusic() };
public object[] Screens {
get {
return _screens;
}
}
public ICommand MenuCommand {
get; set;
}
internal void SwitchBooks(object o) {
if (o.ToString().Equals("Bla.ViewModelBooks")) {
((ViewModelBooks)_screens[0]).SwitchView();
}
}
}
public class CommandViewModel {
private MainWindowViewModel _viewmodel;
public CommandViewModel(MainWindowViewModel viewmodel) {
_viewmodel = viewmodel;
MenuCommand = new RelayCommand(o => {
_viewmodel.SwitchBooks(o);
});
}
public ICommand MenuCommand {
get; set;
}
public string Title {
get;
private set;
}
}
public class RelayCommand ...
ViewBooks.xaml(包含书籍列表。还有这个 TextBlock):
<UserControl x:Class="Bla.ViewBooks"
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:Bla"
mc:Ignorable="d"
d:DesignHeight="900" d:DesignWidth="900">
<UserControl.DataContext>
<local:ViewModelBooks />
</UserControl.DataContext>
<UserControl.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<local:Converter x:Key="Converter" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView x:Name="tileView" ItemsSource="{Binding BooksToDisplay}" Visibility="{Binding IsTile, Converter={StaticResource Converter}}" Grid.Row="0">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Source="{Binding PicUrl}" Width="140" Height="140" Margin="10,10,10,0"/>
<TextBlock Text="{Binding Title}" Width="140" TextAlignment="Center" Margin="10,0,10,10"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Name="listView" Margin="0" ItemsSource="{Binding BooksToDisplay}" Grid.Row="0" Visibility="{Binding IsTile, Converter={StaticResource BooleanToVisibilityConverter}}">
<ListView.View>
<GridView>
<GridViewColumn Header="Titel" Width="Auto" DisplayMemberBinding="{Binding Title}" />
<GridViewColumn Header="Author" Width="Auto" DisplayMemberBinding="{Binding Author}" />
<GridViewColumn Header="Verlag" Width="Auto" DisplayMemberBinding="{Binding Publisher}" />
<GridViewColumn Header="Größe" Width="Auto" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Length}" TextAlignment="Right" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView Name="blaView" Margin="0" ItemsSource="{Binding IsTileViewColl, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" >
<ListView.View>
<GridView>
<GridViewColumn Header="Titel" Width="Auto" DisplayMemberBinding="{Binding}" />
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="{Binding IsTile, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" TextAlignment="Left" />
</Grid>
</UserControl>
我也尝试了没有所有额外绑定(bind)属性的 TextBlock。
ViewModelBooks.cs(包含 IsTile-Property):
namespace Bla {
public class ViewModelBooks : INotifyPropertyChanged {
ObservableCollection<Book> _booksToDisplay = new ObservableCollection<Book>();
FileInfo[] _filesTxt;
private readonly string folderPath = "/folder";
public ViewModelBooks() {
Title = "Bücher";
ImgUrl = "/Resources/ic_map_white_24dp_2x.png";
_selectedView = "tiles";
DirectoryInfo di = new DirectoryInfo(folderPath);
_filesTxt = di.GetFiles("*.txt");
foreach (FileInfo file in _filesTxt) {
try {
Convert.ToInt32(file.Name.Split('_')[0]);
_booksToDisplay.Add(new Book(file));
} catch (Exception e) {
}
}
}
private string _selectedView;
public void SwitchView() {
if (_selectedView.Equals("tiles")) {
IsTile = true;
} else {
IsTile = false;
}
}
public string Title {
get; set;
}
public string ImgUrl {
get;
private set;
}
public ObservableCollection<Book> BooksToDisplay {
get => _booksToDisplay;
set => _booksToDisplay = value;
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) {
if (PropertyChanged == null)
return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private bool _isTile;
public bool IsTile {
get {
return _isTile;
}
set {
if (_isTile == value)
return;
_isTile = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsTile"));
}
}
只要菜单命令更新 IsTile,它就可以工作。但更新从未显示在 TextBlock 中
编辑:现在您可以看到完整的 ViewBooks.xaml
和 ViewModelBooks.cs
。实际上,ViewmodelBooks.cs
也有这段代码(我猜你没兴趣):
public class Book {
string _title;
string _author;
string _publisher;
int _version;
string _url;
string _thumbMD5;
string _fileMD5;
string _areaCode;
string _length;
string _picUrl;
public Book(FileInfo file) {
string oufName = file.FullName.Remove(file.FullName.Length -4, 4) + ".ouf";
FileInfo oufFile = new FileInfo(oufName);
_picUrl = file.FullName.Remove(file.FullName.Length - 4, 4) + ".png";
//_length = string.Format("{0} KB", oufFile.Length >> 10);
float lengthInM = (oufFile.Length >> 10) / 1024f;
_length = lengthInM.ToString("N2") + " MB";
try {
using (StreamReader reader = file.OpenText()) {
string line;
while ((line = reader.ReadLine()) != null) {
string[] lineSeg = line.Split(':');
switch (lineSeg[0]) {
case "Name":
_title = lineSeg[1].Trim();
break;
case "Publisher":
_publisher = lineSeg[1].Trim();
break;
case "Author":
_author = lineSeg[1].Trim();
break;
case "Book Version":
_version = Convert.ToInt32(lineSeg[1].Trim());
break;
case "URL":
_url = lineSeg[1].Trim();
break;
case "ThumbMD5":
_thumbMD5 = lineSeg[1].Trim();
break;
case "FileMD5":
_fileMD5 = lineSeg[1].Trim();
break;
case "Book Area Code":
_areaCode = lineSeg[1].Trim();
break;
}
}
}
} catch (Exception e) {
Debug.WriteLine("ALERT!!! Book-Constructor-Exception: " + e);
}
}
public string Title {
get => _title;
set => _title = value;
}
public string Author {
get => _author;
set => _author = value;
}
public string Publisher {
get => _publisher;
set => _publisher = value;
}
public int Version {
get => _version;
set => _version = value;
}
public string Url {
get => _url;
set => _url = value;
}
public string ThumbMD5 {
get => _thumbMD5;
set => _thumbMD5 = value;
}
public string FileMD5 {
get => _fileMD5;
set => _fileMD5 = value;
}
public string AreaCode {
get => _areaCode;
set => _areaCode = value;
}
public string Length {
get => _length;
set => _length = value;
}
public string PicUrl {
get => _picUrl;
set => _picUrl = value;
}
}
}
class Converter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
return ((bool)value) ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
}
最佳答案
问题来了。在 ViewBooks.xaml 中删除它,您应该没问题。
<UserControl.DataContext>
<local:ViewModelBooks />
</UserControl.DataContext>
这就是为什么这是一个问题。您正在尝试使用 ViewBooks 来显示 MainWindowViewModel 的 ViewModelBooks 副本,它是在 MainWindowViewModel 中创建的:
object[] _screens = new object[] { new ViewModelBooks(), new ViewModelMusic() };
因此,您使 ViewModelBooks
实例成为选项卡的内容。您已经为 ViewModelBooks 创建了一个隐式 DataTemplate,它创建了 ViewBooks 的一个副本,并且一切正常。数据模板被实例化,MainWindowViewModel 的ViewModelBooks
副本作为其DataContext。它创建了一个 ViewBooks 实例,该实例应该从 DataTemplate 继承其 DataContext。
<DataTemplate DataType="{x:Type local:ViewModelBooks}">
<local:ViewBooks />
</DataTemplate>
到目前为止一切顺利。这一切都是应该的。
但是 ViewBooks
创建了它自己的 viewmodel 副本,它替换了它应该继承的 DataContext:
<UserControl.DataContext>
<local:ViewModelBooks />
</UserControl.DataContext>
因此,当 MainWindowViewModel 在它自己的 ViewModelBooks 副本上调用方法时,您可以设置一个断点,这似乎有效,因为 MainWindowViewModel 当然有一个完美的 ViewModelBooks 副本——但 UI 中什么也没有显示,因为 您创建了两个 ViewModelBooks 副本,您在 UI 中看到的副本不是 MainWindowViewModel 拥有的副本。
顺便说一句,这是在 MainWindowViewModel 中创建这些东西的更好方法:
private ViewModelBooks _vmBooks = new ViewModelBooks();
private ViewModelMusic _vmMusic = new ViewModelMusic();
// Initialized in constructor
object[] _screens;
public MainWindowViewModel()
{
_screens = new object[] { _vmBooks, _vmMusic };
MenuCommand = new RelayCommand(o => {
Debug.WriteLine("Menu Command " + o);
SwitchBooks(o);
});
SelectedItem = "Bla.ViewModelBooks";
}
然后就可以使用属性了。 _screens[0]
的问题是,有一天您可能会更改 _screens
中项目的顺序,然后您将不得不追查对 的每个引用>_screens
并修复它。
if (o.ToString().Equals("Bla.ViewModelBooks"))
{
//((ViewModelBooks)_screens[0]).SwitchView();
_vmBooks.SwitchView();
}
此外,我不确定 MenuCommand 从何处获取其参数,但我怀疑您可能会这样做 - 在您进行上述建议的更改后试一试。
if (o is ViewModelBooks) {
((ViewModelBooks)o).SwitchView();
}
最好的办法是让所有选项卡 View 模型都继承自同一个基类,该基类具有虚拟 SwitchView()
方法:
if (o is TabViewModelBase)
{
((TabViewModelBase)o).SwitchView();
}
然后那个 case 会永远处理每个子选项卡,您永远不必再看那段代码。
关于c# TabControl 不会刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43637051/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!