MVVM का उपयोग करके WPF ListView आइटम से एक डबल क्लिक इवेंट फायरिंग


102

MVVM का उपयोग करते हुए एक WPF आवेदन में, मेरे पास एक listcont आइटम के साथ एक usercontrol है। रन समय में, यह ऑब्जेक्ट के संग्रह के साथ सूची को भरने के लिए डेटाबाइंडिंग का उपयोग करेगा।

सूची में आइटम पर डबल क्लिक करने की घटना को संलग्न करने का सही तरीका क्या है ताकि सूची दृश्य में कोई आइटम डबल-क्लिक किया गया हो, दृश्य मॉडल में एक संबंधित घटना को निकाल दिया जाता है और उस पर क्लिक किए गए आइटम का संदर्भ होता है?

यह एक साफ MVVM तरीके से कैसे किया जा सकता है अर्थात व्यू में कोई कोड नहीं?

जवाबों:


76

कृपया, पीछे कोड एक बुरी बात नहीं है। दुर्भाग्य से, WPF समुदाय में काफी लोगों को यह गलत लगा।

MVVM कोड को खत्म करने का एक पैटर्न नहीं है। यह तर्क भाग (कार्यप्रवाह) से दृश्य भाग (उपस्थिति, एनिमेशन, आदि) को अलग करना है। इसके अलावा, आप तर्क वाले भाग का परीक्षण करने में सक्षम हैं।

मैं पर्याप्त परिदृश्यों को जानता हूं जहां आपको कोड लिखना होगा क्योंकि डेटा बाइंडिंग हर चीज का हल नहीं है। आपके परिदृश्य में मैं फ़ाइल के पीछे कोड में DoubleClick ईवेंट को संभालूंगा और इस कॉल को ViewModel को सौंप दूंगा।

सैंपल एप्लिकेशन जो पीछे कोड का उपयोग करते हैं और अभी भी MVVM जुदाई को पूरा करते हैं, उन्हें यहां पाया जा सकता है:

WPF एप्लीकेशन फ्रेमवर्क (WAF) - http://waf.codeplex.com


5
अच्छी तरह से कहा, मैं सिर्फ एक डबल क्लिक करने के लिए उस सभी कोड और एक अतिरिक्त DLL का उपयोग करने से इनकार करता हूं!
एडुआर्डो मोल्टनी 1

4
यह केवल बाइंडिंग चीज़ का उपयोग मुझे एक वास्तविक सिरदर्द दे रहा है। यह 1 बांह के साथ कोड करने के लिए कहा जा रहा है, एक आंख पैच पर 1 आंख, और 1 पैर पर खड़ा है। डबल क्लिक सरल होना चाहिए, और मैं यह नहीं देखता कि यह अतिरिक्त कोड इसके लायक कैसे है।
इचिबन

1
मुझे डर है कि मैं आपसे पूरी तरह सहमत नहीं हूं। यदि आप कहते हैं कि 'पीछे कोड बुरा नहीं है', तो मेरे मन में एक सवाल है: हम बटन के लिए क्लिक इवेंट को क्यों नहीं सौंपते हैं, लेकिन अक्सर बाध्यकारी (कमांड संपत्ति का उपयोग करके) इसके बजाय उपयोग करते हैं?
नाम जी वीयू

21
@Nam Gi VU: मैं हमेशा एक कमांड बाइंडिंग पसंद करूंगा जब वह WPF कंट्रोल द्वारा समर्थित हो। एक कमांड बाइंडिंग 'क्लिक' ईवेंट को ViewModel (जैसे CanExecute) से अधिक करने से अधिक है। लेकिन कमांड केवल सबसे आम परिदृश्यों के लिए उपलब्ध हैं। अन्य परिदृश्यों के लिए हम कोड-बैक फ़ाइल का उपयोग कर सकते हैं और वहां हम गैर-यूआई संबंधी चिंताओं को ViewModel या मॉडल में सौंपते हैं।
जाबे

2
अब मैं आपको और अधिक समझता हूँ! आपके साथ अच्छी चर्चा!
नाम जी VU

73

मैं इसे .NET 4.5 के साथ काम करने में सक्षम हूं। सीधे आगे लगता है और जरूरत के पीछे कोई तीसरा पक्ष या कोड नहीं है।

<ListView ItemsSource="{Binding Data}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Margin="2">
                    <Grid.InputBindings>
                        <MouseBinding Gesture="LeftDoubleClick" Command="{Binding ShowDetailCommand}"/>
                    </Grid.InputBindings>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Image Source="..\images\48.png" Width="48" Height="48"/>
                    <TextBlock Grid.Row="1" Text="{Binding Name}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

2
पूरे क्षेत्र के लिए काम नहीं करता है, उदाहरण के लिए, मैं यह डॉक पैनल पर करता हूं और यह केवल वहीं काम करता है जहां डॉक पैनल (जैसे टेक्स्टब्लॉक, इमेज) के भीतर कुछ है, लेकिन रिक्त स्थान नहीं है।
स्टीफन ड्रू

3
ठीक है - यह पुराना चेस्टनट फिर से ... माउस घटनाओं को प्राप्त करने के लिए पारदर्शी को पृष्ठभूमि सेट करने की आवश्यकता है, जैसा कि stackoverflow.com/questions/7991314/… के
स्टीफन आकर्षित

6
मैं अपना सिर खुजाने की कोशिश कर रहा था कि यह आप सभी के लिए काम कर रहा है और मेरे लिए नहीं। मुझे अचानक एहसास हुआ कि आइटम टेम्पलेट के संदर्भ में डेटा संदर्भ आइटम स्रोत से वर्तमान आइटम है न कि मुख्य विंडो का दृश्य मॉडल। इसलिए मैंने इसे काम करने के लिए निम्नलिखित का उपयोग किया <MouseBinding MouseAction = "LeftDoubleClick" Command = "{Binding Path = DataContext.EditBandCommand, RelativeSource = {RelativeSource AncestorType = {x: Type Window}}}">> इस मामले में EditBandCommand पर काम कर रहे हैं। पृष्ठ के दृश्य पर कमांड को बाध्य इकाई पर नहीं है।
9

naskew में एमवीवीएम लाइट के साथ गुप्त सॉस की आवश्यकता थी, जो कमांड पैरामीटर को डबल-क्लिक की गई सूची बॉक्स में मॉडल ऑब्जेक्ट के रूप में मिल रहा है, और विंडो का डेटा सन्दर्भ उस दृश्य मॉडल पर सेट है जो कमांड को उजागर करता है: <MouseBest Gesture = "LeftDoubleClick "कमांड =" {बाइंडिंग पथ = DataContext.OpenSnapshotCommand, RelativeSource = {RelativeSource AncestorType = {x: Type Window}}} "CommandParameter =" {बाध्यकारी} "/>
MC5

बस वे जोड़ना चाहते हैं जो InputBindings.NET 3.0 से उपलब्ध हैं और सिल्वरलाइट में उपलब्ध नहीं हैं ।
मार्टिन

44

मुझे अटैच्ड कमांड बिहेवियर एंड कमांड्स का इस्तेमाल करना पसंद है । मार्लोन ग्रेच में अटैच्ड कमांड बिहेवियर का बहुत अच्छा कार्यान्वयन है। इनका उपयोग करते हुए, हम फिर ListView के ItemContainerStyle के लिए एक शैली असाइन कर सकते हैं गुण के हैं जो प्रत्येक ListViewItem के लिए कमांड सेट करेगा।

यहां हम माउसडबलक्लिक घटना पर कमांड को सेट किया जा सकता है, और कमांडपैरमीटर, वह डेटा ऑब्जेक्ट होगा जिस पर हम क्लिक करते हैं। यहाँ मैं विज़ुअल ट्री को कमांड प्राप्त करने के लिए यात्रा कर रहा हूँ जो मैं उपयोग कर रहा हूँ, लेकिन आप आसानी से एप्लिकेशन वाइड कमांड बना सकते हैं।

<Style x:Key="Local_OpenEntityStyle"
       TargetType="{x:Type ListViewItem}">
    <Setter Property="acb:CommandBehavior.Event"
            Value="MouseDoubleClick" />
    <Setter Property="acb:CommandBehavior.Command"
            Value="{Binding ElementName=uiEntityListDisplay, Path=DataContext.OpenEntityCommand}" />
    <Setter Property="acb:CommandBehavior.CommandParameter"
            Value="{Binding}" />
</Style>

आदेशों के लिए, आप या तो सीधे एक ICOMAND को लागू कर सकते हैं, या उन कुछ सहायकों का उपयोग कर सकते हैं जो MVVM टूलकिट में आते हैं ।


1
+1 जब मैंने WPF (प्रिज्म) के लिए कम्पोजिट एप्लिकेशन गाइडेंस के साथ काम किया तो यह मेरा पसंदीदा समाधान है।
ट्रैविस हेस्समैन

1
आपके कोड sampleabove में नामस्थान 'acb:' क्या है?
नाम जी वीयू

@NamGiVU acb:= संलग्न उत्तर में पहली कड़ी में कोड पाया जा सकता है
राहेल

मैंने बस कोशिश की और क्लास कमांडबाहोरबाइंडिंग लाइन 99 से शून्य सूचक अपवाद प्राप्त करना। चर "रणनीति" शून्य है। क्या गलत है?
एतवास et

13

मुझे ब्लेंड एसडीके इवेंट ट्रिगर्स के साथ ऐसा करने का बहुत आसान और साफ तरीका मिल गया है। साफ MVVM, पुन: प्रयोज्य और कोई कोड-पीछे।

आपके पास शायद पहले से ही ऐसा कुछ है:

<Style x:Key="MyListStyle" TargetType="{x:Type ListViewItem}">

अब इस तरह ListViewItem के लिए एक ControlTemplate शामिल करें यदि आप पहले से ही एक का उपयोग नहीं करते हैं:

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListViewItem}">
      <GridViewRowPresenter Content="{TemplateBinding Content}"
                            Columns="{TemplateBinding GridView.ColumnCollection}" />
    </ControlTemplate>
  </Setter.Value>
 </Setter>

GridViewRowPresenter एक सूची पंक्ति तत्व बनाते हुए "अंदर" सभी तत्वों का दृश्य मूल होगा। अब हम माउसडबलक्लिक रूटेड ईवेंट देखने के लिए वहां एक ट्रिगर डाल सकते हैं और InvokeCommandAr के माध्यम से एक कमांड को कॉल कर सकते हैं जैसे कि:

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListViewItem}">
      <GridViewRowPresenter Content="{TemplateBinding Content}"
                            Columns="{TemplateBinding GridView.ColumnCollection}">
        <i:Interaction.Triggers>
          <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
          </i:EventTrigger>
        </i:Interaction.Triggers>
      </GridViewRowPresenter>
    </ControlTemplate>
  </Setter.Value>
 </Setter>

यदि आपके पास GridRowPresenter (एक ग्रिड से शुरू होने वाला लम्बा) दृश्य तत्व "ऊपर" है तो आप वहाँ ट्रिगर भी रख सकते हैं।

दुर्भाग्य से MouseDoubleClick घटनाएं प्रत्येक दृश्य तत्व से उत्पन्न नहीं होती हैं (वे नियंत्रण से हैं, लेकिन उदाहरण के लिए फ्रेमवर्क से नहीं)। एक वैकल्पिक हल EventTrigger से एक वर्ग प्राप्त करने के लिए और एक ClickCount 2 के साथ MouseButtonEventArgs की तलाश है। यह प्रभावी रूप से एक ClickCount के साथ सभी गैर- MouseButtonEvents और सभी MoseButtonEvents बाहर फ़िल्टर करता है! = 2

class DoubleClickEventTrigger : EventTrigger
{
    protected override void OnEvent(EventArgs eventArgs)
    {
        var e = eventArgs as MouseButtonEventArgs;
        if (e == null)
        {
            return;
        }
        if (e.ClickCount == 2)
        {
            base.OnEvent(eventArgs);
        }
    }
}

अब हम इसे लिख सकते हैं ('h' ऊपर के सहायक वर्ग का नाम स्थान है):

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type ListViewItem}">
      <GridViewRowPresenter Content="{TemplateBinding Content}"
                            Columns="{TemplateBinding GridView.ColumnCollection}">
        <i:Interaction.Triggers>
          <h:DoubleClickEventTrigger EventName="MouseDown">
            <i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
          </h:DoubleClickEventTrigger>
        </i:Interaction.Triggers>
      </GridViewRowPresenter>
    </ControlTemplate>
  </Setter.Value>
 </Setter>

जैसा कि मुझे पता चला कि अगर आप सीधे GridViewRowPresenter पर ट्रिगर डालते हैं तो समस्या हो सकती है। कोलों के बीच की खाली जगह को संभवतः माउस घटनाएँ प्राप्त नहीं होती हैं (संभवतः संरेखण खिंचाव के साथ उन्हें हल करने के लिए वर्कअराउंड होगा)।
गुंटर

इस मामले में यह संभव है कि GridViewRowPresenter के चारों ओर एक खाली ग्रिड रखा जाए और वहाँ ट्रिगर लगाया जाए। यह काम करने लगता है।
गुंटर

1
ध्यान दें कि यदि आप टेम्पलेट को इस तरह बदलते हैं तो आप ListViewItem के लिए डिफ़ॉल्ट शैली खो देते हैं। यह उस एप्लिकेशन के लिए कोई मायने नहीं रखता था, जिस पर मैं काम कर रहा था क्योंकि यह वैसे भी एक भारी अनुकूलित स्टाइलिंग का उपयोग कर रहा था।
गंटर

6

मुझे पता है कि यह चर्चा एक साल पुरानी है, लेकिन .NET 4 के साथ, क्या इस समाधान पर कोई विचार है? मैं बिल्कुल सहमत हूं कि MVVM की बात फ़ाइल के पीछे एक कोड को खत्म करने के लिए नहीं है। मैं भी बहुत दृढ़ता से महसूस करता हूं कि सिर्फ इसलिए कि कुछ जटिल है, इसका मतलब यह नहीं है कि यह बेहतर है। यहाँ मैं पीछे कोड में क्या रखा है:

    private void ButtonClick(object sender, RoutedEventArgs e)
    {
        dynamic viewModel = DataContext;
        viewModel.ButtonClick(sender, e);
    }

12
आपके डोमेन में आपके द्वारा किए जा सकने वाले कार्यों का प्रतिनिधित्व करने के लिए आपके पास viewmodel के नाम होने चाहिए। आपके डोमेन में "ButtonClick" कार्रवाई क्या है? ViewModel एक दृश्य-अनुकूल संदर्भ में डोमेन के तर्क का प्रतिनिधित्व करता है, यह दृश्य के लिए सहायक नहीं है। तो: ButtonClick कभी भी व्यूमोडल पर नहीं होना चाहिए, viewModel.DeleteSelectedCustomer का उपयोग करें या जो भी इस क्रिया का वास्तव में प्रतिनिधित्व करता है।
Marius

4

आप अपने ViewModel के तरीकों पर घटनाओं को मैप करने के लिए Caliburn के एक्शन फीचर का उपयोग कर सकते हैं । मान लें कि आपके पास एक ItemActivatedविधि है ViewModel, तो संबंधित XAML जैसा दिखेगा:

<ListView x:Name="list" 
   Message.Attach="[Event MouseDoubleClick] = [Action ItemActivated(list.SelectedItem)]" >

अधिक जानकारी के लिए आप कैलिबर्न के दस्तावेज और नमूनों की जांच कर सकते हैं।


4

जब दृश्य बनाया जाता है तो मुझे कमांड को लिंक करना आसान लगता है:

var r = new MyView();
r.MouseDoubleClick += (s, ev) => ViewModel.MyCommand.Execute(null);
BindAndShow(r, ViewModel);

मेरे मामले में BindAndShowऐसा दिखता है (अपडेटकंट्रोल + एवलॉन्डॉक):

private void BindAndShow(DockableContent view, object viewModel)
{
    view.DataContext = ForView.Wrap(viewModel);
    view.ShowAsDocument(dockManager);
    view.Focus();
}

यद्यपि दृष्टिकोण को नए विचारों को खोलने की जो भी विधि है, उसके साथ काम करना चाहिए।


यह मुझे लगता है कि यह केवल XAML में काम करने की कोशिश करने के बजाय सबसे सरल उपाय है।
मास

1

मैंने रुसुई से समाधान देखा साथ लेकिन मैं अभी भी ListViewItem के क्षेत्र को हिट करने में असमर्थ था, जहां कोई पाठ नहीं था - पृष्ठभूमि को पारदर्शी स्थापित करने के बाद भी, इसलिए मैंने इसे विभिन्न टेम्पलेट्स का उपयोग करके हल किया।

यह टेम्पलेट तब के लिए है जब ListViewItem का चयन किया गया है और सक्रिय है:

<ControlTemplate x:Key="SelectedActiveTemplate" TargetType="{x:Type ListViewItem}">
   <Border Background="LightBlue" HorizontalAlignment="Stretch">
   <!-- Bind the double click to a command in the parent view model -->
      <Border.InputBindings>
         <MouseBinding Gesture="LeftDoubleClick" 
                       Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.ItemSelectedCommand}"
                       CommandParameter="{Binding}" />
      </Border.InputBindings>
      <TextBlock Text="{Binding TextToShow}" />
   </Border>
</ControlTemplate>

यह टेम्पलेट तब के लिए है जब ListViewItem का चयन किया गया है और निष्क्रिय है:

<ControlTemplate x:Key="SelectedInactiveTemplate" TargetType="{x:Type ListViewItem}">
   <Border Background="Lavender" HorizontalAlignment="Stretch">
      <TextBlock Text="{Binding TextToShow}" />
   </Border>
</ControlTemplate>

यह ListViewItem के लिए उपयोग की जाने वाली डिफ़ॉल्ट शैली है:

<Style TargetType="{x:Type ListViewItem}">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate>
            <Border HorizontalAlignment="Stretch">
               <TextBlock Text="{Binding TextToShow}" />
            </Border>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
   <Style.Triggers>
      <MultiTrigger>
         <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="True" />
            <Condition Property="Selector.IsSelectionActive" Value="True" />
         </MultiTrigger.Conditions>
         <Setter Property="Template" Value="{StaticResource SelectedActiveTemplate}" />
      </MultiTrigger>
      <MultiTrigger>
         <MultiTrigger.Conditions>
            <Condition Property="IsSelected" Value="True" />
            <Condition Property="Selector.IsSelectionActive" Value="False" />
         </MultiTrigger.Conditions>
         <Setter Property="Template" Value="{StaticResource SelectedInactiveTemplate}" />
      </MultiTrigger>
   </Style.Triggers>
</Style>

मुझे जो पसंद नहीं है वह टेक्स्टब्लॉक और उसके टेक्स्ट बाइंडिंग की पुनरावृत्ति है, मुझे नहीं पता कि II केवल एक ही स्थान पर घोषित करने के आसपास हो सकता है।

मुझे उम्मीद है इससे किसी को सहायता मिलेगी!


यह एक महान समाधान है और मैं एक समान उपयोग करता हूं, लेकिन आपको वास्तव में केवल एक नियंत्रण टेम्पलेट की आवश्यकता है। यदि कोई उपयोगकर्ता डबल क्लिक करने जा रहा है listviewitem, तो वे इस बात की परवाह नहीं करते हैं कि यह पहले से ही चयनित है या नहीं। इसके अलावा यह ध्यान रखना महत्वपूर्ण है कि listviewस्टाइल से मेल खाने के लिए हाइलाइट इफेक्ट का भी इस्तेमाल किया जा सकता है। ऊपर मतदान किया।
डेविड बेंटले

1

मैं अन्तरक्रियाशीलता पुस्तकालय का उपयोग करके .Net 4.7 ढांचे के साथ इस कार्यक्षमता को बनाने में सफल रहा, सबसे पहले XAML फ़ाइल में नाम स्थान की घोषणा करना सुनिश्चित करें

xmlns: मैं = "http://schemas.microsoft.com/expression/2010/interactivity"

फिर नीचे की तरह ListView के अंदर अपने संबंधित InvokeCommandAction के साथ इवेंट ट्रिगर सेट करें।

राय:

<ListView x:Name="lv" IsSynchronizedWithCurrentItem="True" 
          ItemsSource="{Binding Path=AppsSource}"  >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction CommandParameter="{Binding ElementName=lv, Path=SelectedItem}"
                                   Command="{Binding OnOpenLinkCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            <GridViewColumn Header="Developed By" DisplayMemberBinding="{Binding DevelopedBy}" />
        </GridView>
    </ListView.View>
</ListView>

आपके ViewModel पर डबल क्लिक इवेंट का काम करने के लिए ऊपर दिए गए कोड को अपनाना पर्याप्त होगा, हालाँकि मैंने आपको अपने उदाहरण से मॉडल और व्यू मॉडल क्लास जोड़ा है ताकि आपको पूरा आइडिया हो सके।

नमूना:

public class ApplicationModel
{
    public string Name { get; set; }

    public string DevelopedBy { get; set; }
}

देखें मॉडल:

public class AppListVM : BaseVM
{
        public AppListVM()
        {
            _onOpenLinkCommand = new DelegateCommand(OnOpenLink);
            _appsSource = new ObservableCollection<ApplicationModel>();
            _appsSource.Add(new ApplicationModel("TEST", "Luis"));
            _appsSource.Add(new ApplicationModel("PROD", "Laurent"));
        }

        private ObservableCollection<ApplicationModel> _appsSource = null;

        public ObservableCollection<ApplicationModel> AppsSource
        {
            get => _appsSource;
            set => SetProperty(ref _appsSource, value, nameof(AppsSource));
        }

        private readonly DelegateCommand _onOpenLinkCommand = null;

        public ICommand OnOpenLinkCommand => _onOpenLinkCommand;

        private void OnOpenLink(object commandParameter)
        {
            ApplicationModel app = commandParameter as ApplicationModel;

            if (app != null)
            {
                //Your code here
            }
        }
}

मामले में आपको DelegateCommand वर्ग के कार्यान्वयन की आवश्यकता है ।


0

यहाँ एक व्यवहार है कि है कि दोनों पर किया जाता है ListBoxऔर ListView

public class ItemDoubleClickBehavior : Behavior<ListBox>
{
    #region Properties
    MouseButtonEventHandler Handler;
    #endregion

    #region Methods

    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.PreviewMouseDoubleClick += Handler = (s, e) =>
        {
            e.Handled = true;
            if (!(e.OriginalSource is DependencyObject source)) return;

            ListBoxItem sourceItem = source is ListBoxItem ? (ListBoxItem)source : 
                source.FindParent<ListBoxItem>();

            if (sourceItem == null) return;

            foreach (var binding in AssociatedObject.InputBindings.OfType<MouseBinding>())
            {
                if (binding.MouseAction != MouseAction.LeftDoubleClick) continue;

                ICommand command = binding.Command;
                object parameter = binding.CommandParameter;

                if (command.CanExecute(parameter))
                    command.Execute(parameter);
            }
        };
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseDoubleClick -= Handler;
    }

    #endregion
}

यहां अभिभावक को खोजने के लिए उपयोग किए जाने वाले विस्तार वर्ग का उपयोग किया जाता है।

public static class UIHelper
{
    public static T FindParent<T>(this DependencyObject child, bool debug = false) where T : DependencyObject
    {
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        if (parentObject is T parent)
            return parent;
        else
            return FindParent<T>(parentObject);
    }
}

उपयोग:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:coreBehaviors="{{Your Behavior Namespace}}"


<ListView AllowDrop="True" ItemsSource="{Binding Data}">
    <i:Interaction.Behaviors>
       <coreBehaviors:ItemDoubleClickBehavior/>
    </i:Interaction.Behaviors>

    <ListBox.InputBindings>
       <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding YourCommand}"/>
    </ListBox.InputBindings>
</ListView>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.