मैं DataContext संपत्ति का उपयोग करके XAML में एक विंडो पर एक ViewModel कैसे सेट करूं?


96

बहुत सुंदर सवाल यह सब कहते हैं।

मेरे पास एक विंडो है, और ViewModel में पूर्ण नाम स्थान का उपयोग करके DataContext सेट करने की कोशिश की है, लेकिन मुझे कुछ गलत लग रहा है।

<Window x:Class="BuildAssistantUI.BuildAssistantWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="BuildAssistantUI.ViewModels.MainViewModel">

जवाबों:


112

अन्य लोगों द्वारा प्रदान किए गए समाधान के अलावा (जो अच्छे हैं, और सही हैं), XAML में ViewModel को निर्दिष्ट करने का एक तरीका है, फिर भी विशिष्ट ViewModel को View से अलग करें। जब आप अलग-अलग परीक्षण मामलों को लिखना चाहते हैं, तो उन्हें अलग करना उपयोगी होता है।

App.xaml में:

<Application
    x:Class="BuildAssistantUI.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:BuildAssistantUI.ViewModels"
    StartupUri="MainWindow.xaml"
    >
    <Application.Resources>
        <local:MainViewModel x:Key="MainViewModel" />
    </Application.Resources>
</Application>

MainWindow.xaml में:

<Window x:Class="BuildAssistantUI.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{StaticResource MainViewModel}"
    />

अरे वाह ... धन्यवाद। मैंने पहले से ही इसे उत्तर के रूप में चिह्नित किया है, लेकिन आपके अतिरिक्त की सराहना की जाती है। इसका उपयोग करेंगे।
निकोलस

@ निकोलस: अन्य उत्तर प्रश्न के लिए एकदम सही है, इसलिए मैं आपके निर्णय से सहमत हूं
मेरलिन मॉर्गन-ग्राहम

8
बस इस बात का ध्यान रखें कि यह दृष्टिकोण मेनविंडो के प्रत्येक उदाहरण के लिए समान ViewModel उदाहरण का उपयोग करता है। यह ठीक है अगर विंडो सिंगल-इंस्टेंस है क्योंकि यह केस निकलता है, लेकिन अगर आप विंडो के कई इंस्टेंस जैसे एमडीआई या टैब्ड एप्लिकेशन के मामले में नहीं दिखा रहे हैं।
जोश

1
वास्तव में जोश का जवाब बेहतर है क्योंकि यह आपको DataContext पर टाइप-सेफ्टी देता है। इसलिए आप कुछ संपत्ति के नाम / पथ के बारे में चिंता किए बिना सीधे DataContext से जुड़ सकते हैं।
जोश एम।

149

इसके बजाय यह प्रयास करें।

<Window x:Class="BuildAssistantUI.BuildAssistantWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:VM="clr-namespace:BuildAssistantUI.ViewModels">
    <Window.DataContext>
        <VM:MainViewModel />
    </Window.DataContext>
</Window>

3
मुझे यह विकल्प सबसे अच्छा लगता है। यदि वीएम का उपयोग केवल मेनविंडो के लिए किया जाता है, तो क्लीनर लगता है।
एंड्रयू ग्रोथ

13
क्या Windowतत्व पर एक विशेषता का उपयोग करके डेटा संदर्भ सेट करने का एक तरीका है , जैसे DataContext="VM:MainWindowViewModel"?
ओलिवर

यह उचित तरीका है!
जेवियर

मैं पूरी तरह से पूरी तरह से समझ नहीं पा रहा हूं कि एक तरीका दूसरे से बेहतर क्यों है। साथ ही, मैंने कुछ लोगों द्वारा "डायनामिक रिसोर्स" का उपयोग करने के तरीके की तुलना में इन दोनों तरीकों में अंतर को पूरी तरह से नहीं देखा है। यह क्या है?
ट्रैविस ट्यूब्स

1
@ यदि आपको इसे लागू करना होगा, तो आपने MarkupExtensionइसे वीएम पर कभी नहीं किया है, लेकिन आप इसे कन्वर्टर्स के साथ कर सकते हैं ताकि यह सुनिश्चित हो सके कि कनवर्टर का केवल एक ही उदाहरण मौजूद है और इसे xaml से भयंकर रूप से कॉल करें ="{converters:SomethingConverter}", xmlns:convertersकनवर्टर नेमस्पेस पर अंक प्रदान करते हैं। public abstract class BaseValueConverter<T> : MarkupExtension, IValueConverter where T : class, new() { private static T _converter; public override object ProvideValue(IServiceProvider serviceProvider) { return _converter ?? (_converter = new T()); } }
Whazz

11

आपको MainViewModel को इंस्टेंट करना होगा और इसे datacontext के रूप में सेट करना होगा। आपके कथन में इसे केवल स्ट्रिंग मान माना गया है।

     <Window x:Class="BuildAssistantUI.BuildAssistantWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BuildAssistantUI.ViewModels">
      <Window.DataContext>
        <local:MainViewModel/>
      </Window.DataContext>

धन्यवाद, मुझे लगा कि यह कर रहा है।
निकोलस

3

आप कैटल को आज़माना चाह सकते हैं । यह आपको एक डेटाविंडो क्लास (विंडो के बजाय) को परिभाषित करने की अनुमति देता है, और वह क्लास स्वचालित रूप से आपके लिए व्यू मॉडल बनाती है। इस तरह, आप ViewModel की घोषणा का उपयोग कर सकते हैं जैसा कि आपने अपने मूल पोस्ट में किया था, और दृश्य मॉडल अभी भी बनाया जाएगा और DataContext के रूप में सेट किया जाएगा।

इस लेख को एक उदाहरण के लिए देखें ।


1

दृष्टिकोण को निर्दिष्ट करने का यह तरीका भी है:

using Wpf = System.Windows;

public partial class App : Wpf.Application //your skeleton app already has this.
{
    protected override void OnStartup( Wpf.StartupEventArgs e ) //you need to add this.
    {
        base.OnStartup( e );
        MainWindow = new MainView();
        MainWindow.DataContext = new MainViewModel( e.Args );
        MainWindow.Show();
    }
}

<शेख़ी>

पहले से प्रस्तावित सभी समाधानों MainViewModelमें एक पैरामीटर रहित निर्माणकर्ता होना चाहिए।

Microsoft इस धारणा के तहत है कि सिस्टम को पैरामीटर रहित बिल्डरों का उपयोग करके बनाया जा सकता है। यदि आप भी उस धारणा के तहत हैं, तो आगे बढ़ें और कुछ अन्य समाधानों का उपयोग करें।

उन लोगों के लिए जो जानते हैं कि कंस्ट्रक्टरों के पास पैरामीटर होना चाहिए, और इसलिए वस्तुओं की तात्कालिकता को जादू के ढांचे के हाथों में नहीं छोड़ा जा सकता है, जो मैंने ऊपर दिखाया गया है, उसके दृष्टिकोण को निर्दिष्ट करने का उचित तरीका।

</ शेख़ी>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.