Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改DataContext不会更新列表字段_C#_Wpf_Datacontext - Fatal编程技术网

C# 更改DataContext不会更新列表字段

C# 更改DataContext不会更新列表字段,c#,wpf,datacontext,C#,Wpf,Datacontext,我创建了一个新的TextBlock类,该类具有ItemsSource属性,并将该ItemsSource转换为Run对象: public class MultiTypeDynamicTextBlock : TextBlock { public interface ISection { Inline GetDisplayElement(); } public class TextOption : ISection { priv

我创建了一个新的TextBlock类,该类具有ItemsSource属性,并将该ItemsSource转换为Run对象:

public class MultiTypeDynamicTextBlock : TextBlock
{
    public interface ISection
    {
        Inline GetDisplayElement();
    }

    public class TextOption : ISection
    {
        private Run mText;

        public TextOption(string aText)
        {
            mText = new Run();
            mText.Text = aText.Replace("\\n", "\n");
        }

        public Inline GetDisplayElement()
        {
            return mText;
        }
    }

    public class LineBreakOption : ISection
    {
        public Inline GetDisplayElement()
        {
            return new LineBreak();
        }

        public ISection Clone()
        {
            return new LineBreakOption();
        }
    }

    public class ImageOption : ISection
    {
        private InlineUIContainer mContainer;

        public ImageOption(string aDisplay)
        {
            Image lImage;
            lImage = new Image();
            lImage.Source = new BitmapImage(new Uri(Environment.CurrentDirectory + aDisplay));
            lImage.Height = 15;
            lImage.Width = 15;
            mContainer = new InlineUIContainer(lImage);
        }

        public Inline GetDisplayElement()
        {
            return mContainer;
        }
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<ISection>), typeof(MultiTypeDynamicTextBlock),
        new UIPropertyMetadata(new ObservableCollection<ISection>(),
        new PropertyChangedCallback(SetContent)));

    public ObservableCollection<ISection> ItemsSource
    {
        get
        {
            return GetValue(ItemsSourceProperty) as ObservableCollection<ISection>;
        }
        set
        {
            if (ItemsSource != null)
                ItemsSource.CollectionChanged -= CollectionChanged;
            SetValue(ItemsSourceProperty, value);
            SetContent();
            ItemsSource.CollectionChanged += CollectionChanged;
        }
    }

    private void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        SetContent();
    }

    private static void SetContent(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DependencyObject lParent = d;
        MultiTypeDynamicTextBlock lPanel = lParent as MultiTypeDynamicTextBlock;
        if (lPanel != null)
        {
            lPanel.ItemsSource = e.NewValue as ObservableCollection<ISection>;
        }
    }

    private void SetContent()
    {
        if (ItemsSource != null)
        {
            Inlines.Clear();
            foreach (ISection lCurr in ItemsSource)
            {
                Inlines.Add(lCurr.GetDisplayElement());
            }
        }
    }
如果我将ItemsSource直接绑定到DataContext,它就会工作。 但如果我将其绑定到运行时发生更改的对象,例如列表框上的SelectedItem,则在选择新项时不会更新文本

<StackPanel>
    <ListBox x:Name="TheList" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Title}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <StackPanel DataContext="{Binding ElementName=TheList, Path=SelectedItem}">
        <TextBlock Text="{Binding Title}" FontSize="20"/>
        <local:MultiTypeDynamicTextBlock ItemsSource="{Binding Items}"/>
    </StackPanel>
</StackPanel>
有什么原因吗?

在您的示例中,SelectedItem是否有两个属性Title和item?或者项目是viewmodel中的属性?如果答案是后者,那么您可以在下面找到解决方案

我不完全明白你的意思,但我会试试看。 如果您的意思是未设置自定义控件上的ItemsSource,则必须将XAML指向正确的方向。 如果这是您想要实现的目标,您可以在下面找到解决方案。 我所做的是用这行代码将编译器指向正确的源代码:

ItemsSource="{Binding DataContext.Items, RelativeSource={RelativeSource AncestorType=Window}}"
这里您可以说编译器可以在窗口的DataContext或任何可以找到绑定属性的控件中找到绑定属性

谢谢你的帮助。 我通过如下更新MultiTypeDynamicTextBlock来解决此问题:

public class MultiTypeDynamicTextBlock : TextBlock
{
    public interface ISection
    {
        Inline GetDisplayElement();

        ISection Clone();
    }

    public class TextOption : ISection
    {
        private Run mText;

        public TextOption(string aText)
        {
            mText = new Run();
            mText.Text = aText.Replace("\\n", "\n");
        }

        public Inline GetDisplayElement()
        {
            return mText;
        }

        public ISection Clone()
        {
            return new TextOption(mText.Text);
        }
    }

    public class LineBreakOption : ISection
    {
        public Inline GetDisplayElement()
        {
            return new LineBreak();
        }

        public ISection Clone()
        {
            return new LineBreakOption();
        }
    }

    public class SectionList
    {
        private ObservableCollection<ISection> mList;

        public Action CollectionChanged;

        public ObservableCollection<ISection> Items
        {
            get
            {
                ObservableCollection<ISection> lRet = new ObservableCollection<ISection>();
                foreach (ISection lCurr in mList)
                {
                    lRet.Add(lCurr.Clone());
                }
                return lRet;
            }
        }

        public int Count { get { return mList.Count; } }

        public SectionList()
        {
            mList = new ObservableCollection<ISection>();
        }

        public void Add(ISection aValue)
        {
            mList.Add(aValue);
        }

        public SectionList Clone()
        {
            SectionList lRet = new SectionList();
            lRet.mList = Items;
            return lRet;
        }
    }

    public MultiTypeDynamicTextBlock()
    {

    }

    public static readonly DependencyProperty ItemsCollectionProperty =
        DependencyProperty.Register("ItemsCollection", typeof(SectionList), typeof(MultiTypeDynamicTextBlock),
            new UIPropertyMetadata((PropertyChangedCallback)((sender, args) =>
            {
                MultiTypeDynamicTextBlock textBlock = sender as MultiTypeDynamicTextBlock;
                SectionList inlines = args.NewValue as SectionList;

                if (textBlock != null)
                {
                    if ((inlines != null) && (inlines.Count > 0))
                    {
                        textBlock.ItemsCollection.CollectionChanged += textBlock.ResetInlines;
                        textBlock.Inlines.Clear();
                        foreach (ISection lCurr in textBlock.ItemsCollection.Items)
                        {
                            textBlock.Inlines.Add(lCurr.GetDisplayElement());
                        }
                    }
                    else
                    {
                        inlines = new SectionList();
                        inlines.Add(new TextOption("No value set"));
                        textBlock.ItemsCollection = inlines;
                    }
                }
            })));

    public SectionList ItemsCollection
    {
        get
        {
            return (SectionList)GetValue(ItemsCollectionProperty);
        }
        set
        {
            SectionList lTemp;
            if (value == null)
            {
                lTemp = new SectionList();
                lTemp.Add(new TextOption("No value set for property"));
            }
            else
            {
                lTemp = value;
            }
            SetValue(ItemsCollectionProperty, lTemp);
        }
    }

    private void ResetInlines()
    {
        Inlines.Clear();
        foreach (ISection lCurr in ItemsCollection.Items)
        {
            Inlines.Add(lCurr.GetDisplayElement());
        }
    }
}
我更新绑定为MultiTypeDynamicTextBlock.SectionList类型的字段

只要我使用的是复制克隆,它就可以工作,出于某种原因,当我不克隆时,它会从列表中的显示中删除值,如果有人知道我为什么喜欢学习,但我设法绕过了它。 窗口的XAML是:

<StackPanel>
    <ListBox x:Name="TheList" ItemsSource="{Binding GeneralItems}" SelectedItem="{Binding SelectedItem}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Title}" FontSize="20"/>
                    <local:MultiTypeDynamicTextBlock ItemsCollection="{Binding Items}" Margin="20,0,0,0"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <StackPanel DataContext="{Binding GeneralItems, Path=SelectedItem}">
        <TextBlock Text="{Binding Title}" FontSize="20"/>
        <local:MultiTypeDynamicTextBlock DataContext="{Binding Items}" ItemsCollection="{Binding}" Margin="20,0,0,0"/>
    </StackPanel>
</StackPanel>

如果我将ItemsSource直接绑定到DataContext,这是什么意思。?您给出的xaml示例是工作示例还是非工作示例?添加此ItemsSource={Binding}Items集合中的对象类型是什么?Nit-此示例不起作用。Aravind-你想让我在哪里添加这个,MultiTypeDynamicTextBlock已经有一个ItemsSource,所以我不能再给它一个,更改绑定会将它指向另一个位置Loetn-Title是string类型,Items是ObservableCollectionYou是对的,问题不清楚答案是第一个,所选项目有两个属性,标题和项目,当选择新记录时,标题会更新,但项目不是第一个,项目不会更改,我们现在查看的是属于该类另一个实例的不同项目。第二,我添加了这段代码,但仍然不起作用。
public class MultiTypeDynamicTextBlock : TextBlock
{
    public interface ISection
    {
        Inline GetDisplayElement();

        ISection Clone();
    }

    public class TextOption : ISection
    {
        private Run mText;

        public TextOption(string aText)
        {
            mText = new Run();
            mText.Text = aText.Replace("\\n", "\n");
        }

        public Inline GetDisplayElement()
        {
            return mText;
        }

        public ISection Clone()
        {
            return new TextOption(mText.Text);
        }
    }

    public class LineBreakOption : ISection
    {
        public Inline GetDisplayElement()
        {
            return new LineBreak();
        }

        public ISection Clone()
        {
            return new LineBreakOption();
        }
    }

    public class SectionList
    {
        private ObservableCollection<ISection> mList;

        public Action CollectionChanged;

        public ObservableCollection<ISection> Items
        {
            get
            {
                ObservableCollection<ISection> lRet = new ObservableCollection<ISection>();
                foreach (ISection lCurr in mList)
                {
                    lRet.Add(lCurr.Clone());
                }
                return lRet;
            }
        }

        public int Count { get { return mList.Count; } }

        public SectionList()
        {
            mList = new ObservableCollection<ISection>();
        }

        public void Add(ISection aValue)
        {
            mList.Add(aValue);
        }

        public SectionList Clone()
        {
            SectionList lRet = new SectionList();
            lRet.mList = Items;
            return lRet;
        }
    }

    public MultiTypeDynamicTextBlock()
    {

    }

    public static readonly DependencyProperty ItemsCollectionProperty =
        DependencyProperty.Register("ItemsCollection", typeof(SectionList), typeof(MultiTypeDynamicTextBlock),
            new UIPropertyMetadata((PropertyChangedCallback)((sender, args) =>
            {
                MultiTypeDynamicTextBlock textBlock = sender as MultiTypeDynamicTextBlock;
                SectionList inlines = args.NewValue as SectionList;

                if (textBlock != null)
                {
                    if ((inlines != null) && (inlines.Count > 0))
                    {
                        textBlock.ItemsCollection.CollectionChanged += textBlock.ResetInlines;
                        textBlock.Inlines.Clear();
                        foreach (ISection lCurr in textBlock.ItemsCollection.Items)
                        {
                            textBlock.Inlines.Add(lCurr.GetDisplayElement());
                        }
                    }
                    else
                    {
                        inlines = new SectionList();
                        inlines.Add(new TextOption("No value set"));
                        textBlock.ItemsCollection = inlines;
                    }
                }
            })));

    public SectionList ItemsCollection
    {
        get
        {
            return (SectionList)GetValue(ItemsCollectionProperty);
        }
        set
        {
            SectionList lTemp;
            if (value == null)
            {
                lTemp = new SectionList();
                lTemp.Add(new TextOption("No value set for property"));
            }
            else
            {
                lTemp = value;
            }
            SetValue(ItemsCollectionProperty, lTemp);
        }
    }

    private void ResetInlines()
    {
        Inlines.Clear();
        foreach (ISection lCurr in ItemsCollection.Items)
        {
            Inlines.Add(lCurr.GetDisplayElement());
        }
    }
}
<StackPanel>
    <ListBox x:Name="TheList" ItemsSource="{Binding GeneralItems}" SelectedItem="{Binding SelectedItem}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Title}" FontSize="20"/>
                    <local:MultiTypeDynamicTextBlock ItemsCollection="{Binding Items}" Margin="20,0,0,0"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <StackPanel DataContext="{Binding GeneralItems, Path=SelectedItem}">
        <TextBlock Text="{Binding Title}" FontSize="20"/>
        <local:MultiTypeDynamicTextBlock DataContext="{Binding Items}" ItemsCollection="{Binding}" Margin="20,0,0,0"/>
    </StackPanel>
</StackPanel>