简体   繁体   中英

Set different datacontext in one view

I have 2 Windows. From the first window I'm calling second :

var window = new WindowButtonClick("Graphic") {DataContext = new GraphicViewModel()};
window.ShowDialog();

Here is XAML of second window:

<Window x:Class="WindowButtonClick"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graphic="clr-namespace:Windows.Graphic"
WindowStartupLocation="CenterScreen" >
<Window.Resources>
      <DataTemplate DataType="{x:Type graphic:GraphicViewModel}">
        <graphic:Graphic />
      </DataTemplate>
</Window.Resources>
<Grid>
    <ContentControl Content="{Binding}"/>
</Grid>

and constructor:

public WindowButtonClicks(string title)
{
    InitializeComponent();
    Title = Application.Current.Resources[title].ToString();
}

So how can I set DataContext, that it will show title that I pass in constructor as window Title and ContentControl will show one of the viewModels(GraphicViewModel in this case) ?

This is a common problem in WPF. Luckily, it has a simple solution. You'll need to use a RelativeSource Binding . So you'll need to set the DataContext to one object, whose properties you can data bind simply to like this:

<TextBox Text="{Binding PropertyOfDataContext}" />

And for any properties that are declared in the Window or UserControl , you can use the RelativeSource Binding like this:

<TextBox Text="{Binding PropertyOfWindow, RelativeSource={RelativeSource AncestorType={
    x:Type YourXamlPrefix:YourWindow}}}" />

UPDATE >>>

You said:

I will have 20 ViewModels, that I want to load to ContentControl

If you had only provided all of the relevant information when asking your question, then you would have had a better answer by now. This is a different problem, but can be fixed just as easily. In this case, you can just set your view models to their views using DataTemplate s... just define one for each view model/view pair like this:

<DataTemplate DataType="{x:Type ViewModels:ViewModel1}">
    <Views:View1 />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:ViewModelN}">
    <Views:ViewN />
</DataTemplate>

Note that I did not set the x:Key values... this means that the specified views will be implicitly rendered by the Framework whenever it comes across objects of the relevant type. Then to display the View1 from this example, you'd just need to do this:

<ContentControl Content="{PropertyOfTypeViewModel1}" />

UPDATE 2 >>>

Wow... I really hope that you've explained your problem properly this time because this is my last update. So I can't really see a problem with what you are asking for... you want to set a property in the constructor to be displayed as the Window.Title . This would definitely work:

public WindowButtonClicks(string title)
{
    InitializeComponent();
    Title = "Some Title";
}

So if your code doesn't work, then you must have a problem with your call to Application.Current.Resources[title] ... have you actually checked whether that returns a value or not? If it does, then you have a real problem, because it is perfectly acceptable to set the Window.Title like this.

If Application.Current is returning null , then just make sure that you set it to an instance of MainWindow.xaml.cs in the code behind:

// In MainWindow.xaml.cs constructor
Application.Current = this;

Other than that, your problem is impossible to determine from the information that you have provided.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM