我正在尝试构建一个应用程序,从api收集水坝和天气预报的信息,并显示数据给用户。
如下图所示,大坝信息和天气预报信息的主页看起来应该是相似的。蓝色打印
我想为card创建一个组件,我可以为数据重用它。换句话说,我想把mainCards放到mainPage中,这样我就可以有一个全是卡片的页面。然后,我想把mainPage放在mainWindow的上面。
我想改变紫色卡片内部的值,当我点击左边的菜单按钮,上面写着"大坝信息"one_answers"天气信息"。当我按下"大坝信息"时;按钮,我想要紫色的卡从API获取大坝数据,并显示在屏幕上。"天气信息"也一样。按钮。
问题是,我可以清楚地看到,当我运行代码并在控制台上显示它们时,我绑定到卡片中的文本块的值发生了变化。但实际的UI不会更新更改。INotifyProperty表示,当我按下按钮时,我为当前视图实现的视图模型会发生变化。它还说,当我按下按钮时,紫色卡片组件的视图模型中的值(我绑定到紫色卡片的文本块)会发生变化。
我实现了一个基类,实现了INotifyPropertyChanged为所有视图模型,和RelayCommand为所有命令。
我假设使用INotifyPropertyChanged,视图将自动更改UI值,但它没有。我已经尝试将绑定模式设置为Two Way,但它不起作用。我尝试在主页(包含大量紫色卡片组件的页面)的视图模型中设置某些值,然后使紫色卡片视图模型获取并反映它。但是它不工作。
请帮帮我。这个问题我已经处理了一个星期了。我没有多少时间去纠结于不断变化的视图及其组成部分。我是MVVM模式和WPF的新手,完全迷路了。
主窗口的xaml如下所示
<Grid>
<RadioButton Content="Dam Info"
Command="{Binding ChangeMainPageForDamCommand}"
CommandParameter="Dam"/>
<RadioButton Content="Weather Info"
Command="{Binding ChangeMainPageForWeatherCommand}"
CommandParameter="Weather"/>
<RadioButton Content="My data"
Command="{Binding DetailPageCommand}"/>
<ContentControl Content="{Binding CurrentView,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
主窗口视图模型如下图
private object _currentView;
public object CurrentView
{
get { return _currentView; }
set
{
_currentView = value;
OnPropertyChanged();
}
}
public RelayCommand MainPageCommand { get; set; }
public RelayCommand DetailPageCommand { get; set; }
public RelayCommand ChangeMainPageForDamCommand { get; set; }
public RelayCommand ChangeMainPageForWeatherCommand { get; set; }
public MainPageViewModel DamMainPageVM { get; set; }
public MainPageViewModel WeatherMainPageVM { get; set; }
public MainPageViewModel MainPageVM { get; set; }
public DetailPageViewModel DetailPageVM { get; set; }
public MainWindowViewModel()
{
MainPageVM = new MainPageViewModel("Dam");
CurrentView = MainPageVM;
DetailPageVM = new DetailPageViewModel();
ChangeMainPageForDamCommand = new RelayCommand(o =>
{
CurrentView = null;
DamMainPageVM = new MainPageViewModel("Dam");
CurrentView = DamMainPageVM;
Debug.WriteLine("ChangeMainPageFor Dam Command executed");
});
ChangeMainPageForWeatherCommand = new RelayCommand(o =>
{
WeatherMainPageVM = new MainPageViewModel("Weather");
CurrentView = WeatherMainPageVM;
Debug.WriteLine("ChangeMainPageFor Weather Command executed");
});
DetailPageCommand = new RelayCommand(o =>
{
CurrentView = DetailPageVM;
});
}
包含卡片的mainPage的xaml如下所示
<Grid>
<components:MainCard/>
<components:MainCard/>
<components:MainCard/>
<components:MainCard/>
<components:MainCard/>
<components:MainCard/>
</Grid>
主页面的视图模型如下所示
public MainCardDatum MainCardDatumItem = new MainCardDatum();
public RelayCommand GetDamDetailCommand { get; set; }
private MainCardViewModel _mainCardViewModel;
public MainCardViewModel MainCardViewModel
{
get
{
return _mainCardViewModel;
}
set
{
_mainCardViewModel = value;
OnPropertyChanged(nameof(MainCardViewModel));
}
}
public MainPageViewModel() { }
public MainPageViewModel(string pageName)
{
var d = new MainCardViewModel(pageName);
GetMainPage(pageName);
Debug.WriteLine(pageName+" is ON");
}
public void GetMainPage(string pageName)
{
GenerateMainCard(pageName);
Debug.WriteLine(pageName+" made the page.");
}
private void GenerateMainCard(string pageName)
{
if (pageName == "Dam")
{
MainCardDatumItem.Id = 1;
MainCardDatumItem.MainCardName = "damDummyInfoName";
MainCardDatumItem.MainCardOption = "damDummyInfoOption";
}
else if (pageName == "Weather")
{
MainCardDatumItem.Id = 1;
MainCardDatumItem.MainCardName = "weatherDummyInfoName";
MainCardDatumItem.MainCardOption = "weatherDummyInfoOption";
}
else
{
Debug.Write("What?");
}
}
主卡(紫卡组件)xaml在
<Grid>
<StackPanel>
<TextBlock Name="nameHehe"
Text="{Binding MainCardName,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="optionHehe"
Text="{Binding MainCardOption}"/>
</StackPanel>
<Button Background="Transparent"
Command="{Binding GetDamDetailCommand}"/>
</Grid>
最后,主卡(紫色卡组件)的视图模型在下面
public MainPageViewModel MainPageVM = new MainPageViewModel();
private string _mainCardName;
public string MainCardName
{
get
{
return _mainCardName;
}
set
{
_mainCardName = value;
OnPropertyChanged(nameof(MainCardName));
}
}
private string _mainCardOption;
public string MainCardOption
{
get
{
return _mainCardOption;
}
set
{
_mainCardOption = value;
OnPropertyChanged(nameof(MainCardOption));
}
}
public RelayCommand ClickCommand { get; set; }
public RelayCommand GetDamDetailCommand { get; set; }
public RelayCommand GetWeatherDetailCommand { get; set; }
public MainCardViewModel()
{
GenerateCardsForDam();
GetDamDetailCommand = new RelayCommand(o =>
{
MainCardName = "changed1";
MainCardOption = "changed2";
});
}
public MainCardViewModel(string pageName)
{
if (pageName == "Dam")
GenerateCardsForDam();
else
GenerateCardsForWeather();
GetDamDetailCommand = new RelayCommand(o =>
{
GenerateCardsForWeather();
});
}
public void GenerateCardsForDam()
{
MainCardName = "DamName1";
MainCardOption = "DamOption1";
Debug.WriteLine("GenerateCardsForDam executed");
}
public void GenerateCardsForWeather()
{
MainCardName = "WeatherName1";
MainCardOption = "WeatherOption1";
Debug.WriteLine("GenerateCardsForWeather executed");
}
我删除了xaml中与此问题无关的所有不必要的代码。
我做错了什么?请帮助。
此外,它将是美妙的知道任何不和服务器,我可以问和回答有关编程的问题。我很难用文字解释这个问题。如果你知道,请告诉我。
非常感谢您的阅读。对不起,解释得有点乱。
https://github.com/yk170901/dnw.git上面是我的项目的Github存储库。我试图正确添加它,但不知何故,当我试图上传它时,项目文件夹变成空的。所以我添加了一个zip文件,希望你能看到这个zip文件的问题。很抱歉给您带来不便。
您在App.xaml中为MainPage (UserControl)定义了一个DataTemplate .
<DataTemplate DataType="{x:Type viewModel:MainPageViewModel}">
<view:MainPage/>
</DataTemplate>
当这个DataTemplate被应用时,它被期望实例化一个MainPage,并将MainPageViewModel的实例设置为MainPage的DataContext。
但是,您在MainPage.xaml中添加了如下所示的代码块。
<UserControl.DataContext>
<viewModels:MainPageViewModel/>
</UserControl.DataContext>
这意味着当MainPage被实例化时,MainPageViewModel的实例也将被实例化,并且该实例将被设置为MainPage的DataContext。这似乎阻止了DataTemplate按预期工作。
因此,解决方案是删除MainPage.xaml中的代码块。此外,我发现无论MainPageViewModel的实例如何,MainPage的外观都是相同的,因此您将无法检查其外观的差异。