[c#] XAML में कैनवास की बच्चों की संपत्ति को बांधना संभव है?


Answers

<ItemsControl ItemsSource="{Binding Path=Circles}">
    <ItemsControl.ItemsPanel>
         <ItemsPanelTemplate>
              <Canvas Background="White" Width="500" Height="500"  />
         </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Fill="{Binding Path=Color, Converter={StaticResource colorBrushConverter}}" Width="25" Height="25" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
            <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>
Question

मैं थोड़ा आश्चर्यचकित हूं कि कैनवास के लिए बाध्यकारी स्थापित करना संभव नहीं है। XAML के माध्यम से बच्चे। मुझे कोड-बैक दृष्टिकोण का सहारा लेना पड़ा जो ऐसा कुछ दिखता है:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    DesignerViewModel dvm = this.DataContext as DesignerViewModel;
    dvm.Document.Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged);

    foreach (UIElement element in dvm.Document.Items)
        designerCanvas.Children.Add(element);
}

private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    ObservableCollection<UIElement> collection = sender as ObservableCollection<UIElement>;

    foreach (UIElement element in collection)
        if (!designerCanvas.Children.Contains(element))
            designerCanvas.Children.Add(element);

    List<UIElement> removeList = new List<UIElement>();
    foreach (UIElement element in designerCanvas.Children)
        if (!collection.Contains(element))
            removeList.Add(element);

    foreach (UIElement element in removeList)
        designerCanvas.Children.Remove(element);
}

मैं इस तरह XAML में बस बाध्यकारी स्थापित करना चाहता हूं:

<Canvas x:Name="designerCanvas"
        Children="{Binding Document.Items}"
        Width="{Binding Document.Width}"
        Height="{Binding Document.Height}">
</Canvas>

क्या कोड-पीछे दृष्टिकोण का उपयोग किये बिना इसे पूरा करने का कोई तरीका है? मैंने इस विषय पर कुछ गुगल किया है, लेकिन इस विशिष्ट समस्या के लिए बहुत कुछ नहीं आया है।

मुझे अपने वर्तमान दृष्टिकोण को पसंद नहीं है क्योंकि यह व्यू मॉडेल के बारे में जागरूक दृश्य बनाकर मेरे अच्छे मॉडल-व्यू-व्यू मॉडेल को मिलाता है।




ItemsControl कंट्रोल को अन्य संग्रहों से भी यूआई नियंत्रणों के गतिशील संग्रह बनाने के लिए डिज़ाइन किया गया है, यहां तक ​​कि गैर-यूआई डेटा संग्रह भी।

आप Canvas पर आकर्षित करने के लिए एक ItemsControl को टेम्पलेट कर सकते हैं। आदर्श तरीका में बैकिंग पैनल को Canvas सेट करना और फिर Canvas सेट करना शामिल है। Canvas.Left और Canvas । तत्काल बच्चों पर गुण। मैं इसे काम नहीं कर सका क्योंकि ItemsControl अपने बच्चों को कंटेनर से लपेटता है और इन कंटेनरों पर Canvas गुणों को सेट करना मुश्किल है।

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

<ItemsControl x:Name="Collection" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:MyPoint}">
            <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                <Ellipse Width="10" Height="10" Fill="Black" Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}"/>
            </Canvas>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

यहां कोड है जिसके बाद मैं स्रोत संग्रह सेट अप करता था:

List<MyPoint> points = new List<MyPoint>();

points.Add(new MyPoint(2, 100));
points.Add(new MyPoint(50, 20));
points.Add(new MyPoint(200, 200));
points.Add(new MyPoint(300, 370));

Collection.ItemsSource = points;

MyPoint एक कस्टम क्लास है जो System संस्करण की तरह व्यवहार करता है। मैंने इसे प्रदर्शित करने के लिए बनाया है कि आप अपनी खुद की कस्टम कक्षाओं का उपयोग कर सकते हैं।

एक अंतिम विवरण: आप आइटम्ससोर्स प्रॉपर्टी को अपने इच्छित संग्रह में जोड़ सकते हैं। उदाहरण के लिए:

<ItemsControls ItemsSource="{Binding Document.Items}"><!--etc, etc...-->

आइटम नियंत्रण और यह कैसे काम करता है के बारे में अधिक जानकारी के लिए, इन दस्तावेजों को देखें: एमएसडीएन लाइब्रेरी संदर्भ ; डेटा टेम्पलेटिंग ; आइटम कंट्रोल पर डॉ डब्ल्यूपीएफ की श्रृंखला




Links