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# 如何在ItemsControl中绑定DataTemplate_C#_Wpf_Xaml_Binding_Itemscontrol - Fatal编程技术网

C# 如何在ItemsControl中绑定DataTemplate

C# 如何在ItemsControl中绑定DataTemplate,c#,wpf,xaml,binding,itemscontrol,C#,Wpf,Xaml,Binding,Itemscontrol,我不理解ItemTemplate中的DataTemplate。我有一个ObservableCollection“StringViewModel”转录,它为ItemsControl提供ItemsSource。使用StringViewModel填充转录集合将正确显示这些字符串 在显示每个字符串时,我希望XAML绑定调用MyConverter,以便在显示的每个项目上运行额外的代码。(我不想更改显示的内容,而只是根据显示内容的位置执行一些操作) 在下面的代码中,从未调用MyConverter 对Item

我不理解ItemTemplate中的DataTemplate。我有一个ObservableCollection“StringViewModel”转录,它为ItemsControl提供ItemsSource。使用StringViewModel填充转录集合将正确显示这些字符串

在显示每个字符串时,我希望XAML绑定调用MyConverter,以便在显示的每个项目上运行额外的代码。(我不想更改显示的内容,而只是根据显示内容的位置执行一些操作)

在下面的代码中,从未调用MyConverter

对ItemsControl中显示的每个项目调用MyConverter的最佳方式是什么

感谢您的帮助

C#

公共类StringViewModel:FrameworkElement{…}
私有ObservableCollection转录=新ObservableCollection();
公共可观测收集转录
{
得到
{
返回转录;
}
设置
{
转录=值;
}
}
XAML


我尝试将此更改为:

<ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StringViewModel ft="{Binding Path=., Converter={StaticResource MyConverter}}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

结果:

已为ItemsControl容器类型的项忽略ItemTemplate和ItemTemplateSelector;类型='StringViewModel'

怎么办

StringViewModel定义为:

  public class StringViewModel : FrameworkElement, INotifyPropertyChanged
{

    public StringViewModel()
    {
    }

    public StringViewModel(
        Point topleft, 
        string text, 
        double fontsizediu,                         
        SolidColorBrush brush, 
        Func<FormattedText,FormattedText> f,        
        double lineheight)
    {
        this.text = text;
        this.emSize = fontsizediu;                 
        this.color = brush;
        this.topleft = topleft;
        this.lineheight = lineheight;              
        this.f = f;
    }

    protected override void OnRender(DrawingContext dc)
    {

        ft = new FormattedText(
            text, 
            CultureInfo.CurrentCulture, 
            FlowDirection.LeftToRight,
            new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
            emSize, 
            color);


        ft.TextAlignment = TextAlignment.Left;

        // apply special styles
        ft = f(ft);
        dc.DrawText(ft, topleft);

    }

    private string text;
    private double emSize;
    private SolidColorBrush color;
    private Func<FormattedText, FormattedText> f;

    public Point topleft;
    private double? Lineheight;


    private FormattedText _ft;
    public FormattedText ft
    {
        get
        {
            return _ft;
        }
        set
        {
            if (_ft != value)
            {
                _ft = value;
                OnPropertyChanged("ft");
            }
        }
    }
公共类StringViewModel:FrameworkElement,INotifyPropertyChanged
{
公共StringViewModel()
{
}
公共视图模型(
左上角,
字符串文本,
双方斯泽度,
SolidColorBrush,
Func f,
双线宽)
{
this.text=文本;
this.emSize=fontsizedu;
这个颜色=画笔;
this.topleft=topleft;
this.lineheight=线宽;
这个。f=f;
}
受保护的覆盖无效OnRender(DrawingContext dc)
{
ft=新格式化文本(
文本,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
新字体(新FontFamily(“Segoe脚本”)、FontStyles.Italic、FontWeights.Normal、FontStreats.Normal),
emSize,
颜色);
ft.TextAlignment=TextAlignment.Left;
//应用特殊样式
ft=f(ft);
dc.DrawText(英尺,左上角);
}
私有字符串文本;
私人双户型;
私人纯色刷色;
私人职能;
公共点左上角;
私人双线高度;
私有格式化文本_ft;
公共格式化文本
{
得到
{
返回_ft;
}
设置
{
如果(_ft!=值)
{
_ft=值;
不动产变更(“ft”);
}
}
}

更新:

我建议您不要在ViewModel中实现渲染,实际上您的StringViewModel应该是这样的StringModel:(只包含一些属性)

然后,在转换器中实现渲染:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var stringviewmodel = value as StringModel;
        if (stringviewmodel != null)
        {
            stringviewmodel.ft = new FormattedText(
           stringviewmodel.text,
           CultureInfo.CurrentCulture,
           FlowDirection.LeftToRight,
           new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
           stringviewmodel.emSize,
           stringviewmodel.color);


            stringviewmodel.ft.TextAlignment = TextAlignment.Left;

            // apply special styles

            Image myImage = new Image();

            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext dc = drawingVisual.RenderOpen();
            dc.DrawText(stringviewmodel.ft, stringviewmodel.topleft);
            dc.Close();

            RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 120, 96, PixelFormats.Pbgra32);
            bmp.Render(drawingVisual);
            myImage.Source = bmp;

            return myImage;
        }
        else
        {
            return null;
        }
    }
下面是itemcontrol的代码:

 <ItemsControl x:Name="ic" ItemsSource="{Binding LST}" Margin="0,0,143,185">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel 
                        Background="Transparent"
                         />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Converter={StaticResource myconverter}}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

主要代码是:

 public partial class MainWindow : Window
{
    private List<StringModel> lst;

    public List<StringModel> LST
    {
        get { return lst; }
        set { lst = value; }
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        LST = new List<StringModel>();

        StringModel vm = new StringModel(new Point(20, 20), "123", 14, Brushes.Red, 2);
        LST.Add(vm);

        vm = new StringModel(new Point(20, 20), "456", 16, Brushes.Blue, 3);
        LST.Add(vm);

        vm = new StringModel(new Point(20, 20), "789", 18, Brushes.Green, 4);
        LST.Add(vm);



    }
}
公共部分类主窗口:窗口
{
私人名单;
公共列表LST
{
获取{return lst;}
设置{lst=value;}
}
公共主窗口()
{
初始化组件();
this.DataContext=this;
LST=新列表();
StringModel vm=新的StringModel(新点(20,20),“123”,14,画笔。红色,2);
一级添加(vm);
vm=新的StringModel(新点(20,20),“456”,16,画笔。蓝色,3);
一级添加(vm);
vm=新的StringModel(新点(20,20),“789”,18,画笔。绿色,4);
一级添加(vm);
}
}
最后,它的影响:


哪个结果(效果)您想实现吗?您已经为ItemsControl设置了ItemsSource,但没有为Canvas和ContentControl设置内容。@如果没有ItemsControl.ItemTemplate部分,转录中的字符串将正确显示在画布上的正确位置。最后,我想使用每个显示项的位置来执行visual在转换器内进行命中测试。转录集合是一个类型FormattedText的动态变化集合。你的意思是,如果你添加
,转换器从未被调用?如果没有
,它会在画布中正确显示
转录
。但我写了一个简单的示例,它可以工作。请参阅我的临时答案。@Rang没错。转录是FormattedText的可观察集合有关系吗?除了直接在XAML中绑定ItemsSource外,我得到“System.Windows.Data错误:26:ItemsControl容器类型的项已忽略ItemTemplate和ItemTemplateSelector;type='StringViewModel'”当使用@AlanWayne
StringViewModel
是一个类时,可能是因为它有很多属性。所以你不应该在这里使用ContentControl。我已经更新了我的答案。如果我这样做了:我仍然得到System.Windows.Data.Error 26怎么办???为什么要将
放进去k:StringViewModel
这里?你能提供StringViewModel的代码并绘制一些你想要显示的ItemsControl的图片吗?我在最上面的问题中添加了代码。对不起,我不知道如何绘制图片。但是,在使用时,上面的ItemsControl将显示格式化的控件
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var stringviewmodel = value as StringModel;
        if (stringviewmodel != null)
        {
            stringviewmodel.ft = new FormattedText(
           stringviewmodel.text,
           CultureInfo.CurrentCulture,
           FlowDirection.LeftToRight,
           new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
           stringviewmodel.emSize,
           stringviewmodel.color);


            stringviewmodel.ft.TextAlignment = TextAlignment.Left;

            // apply special styles

            Image myImage = new Image();

            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext dc = drawingVisual.RenderOpen();
            dc.DrawText(stringviewmodel.ft, stringviewmodel.topleft);
            dc.Close();

            RenderTargetBitmap bmp = new RenderTargetBitmap(180, 180, 120, 96, PixelFormats.Pbgra32);
            bmp.Render(drawingVisual);
            myImage.Source = bmp;

            return myImage;
        }
        else
        {
            return null;
        }
    }
 <ItemsControl x:Name="ic" ItemsSource="{Binding LST}" Margin="0,0,143,185">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel 
                        Background="Transparent"
                         />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Converter={StaticResource myconverter}}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
 public partial class MainWindow : Window
{
    private List<StringModel> lst;

    public List<StringModel> LST
    {
        get { return lst; }
        set { lst = value; }
    }

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        LST = new List<StringModel>();

        StringModel vm = new StringModel(new Point(20, 20), "123", 14, Brushes.Red, 2);
        LST.Add(vm);

        vm = new StringModel(new Point(20, 20), "456", 16, Brushes.Blue, 3);
        LST.Add(vm);

        vm = new StringModel(new Point(20, 20), "789", 18, Brushes.Green, 4);
        LST.Add(vm);



    }
}