gpt4 book ai didi

c# - 如何在 ItemsControl 中绑定(bind) DataTemplate

转载 作者:太空宇宙 更新时间:2023-11-03 10:40:19 24 4
gpt4 key购买 nike

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

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

在以下代码中,MyConverter 从未被调用。

在 ItemsControl 中显示的每个项目上调用 MyConverter 的最佳方法是什么?

感谢任何帮助。

C#

public class StringViewModel : FrameworkElement {...}

private ObservableCollection<StringViewModel> transcription = new ObservableCollection<StringViewModel>();
public ObservableCollection<StringViewModel> Transcription
{
get
{
return transcription;
}
set
{
transcription = value;
}
}

XAML

<ItemsControl 
ItemsSource="{Binding Transcription}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas
Background="Transparent"
Width="{x:Static h:Constants.widthCanvas}"
Height="{x:Static h:Constants.heightCanvas}"
/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate> <!-- THIS DOES NOT WORK -->

<ContentControl Content="{Binding Converter={StaticResource MyConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

我试图将其更改为:

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

结果:

ItemTemplate 和 ItemTemplateSelector 对于已经属于 ItemsControl 容器类型的项目将被忽略; Type='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");
}
}
}

最佳答案

更新:

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

public class StringModel :  INotifyPropertyChanged
{

public StringModel()
{
}

public StringModel(
Point topleft,
string text,
double fontsizediu,
SolidColorBrush brush,
double lineheight)
{
this.text = text;
this.emSize = fontsizediu;
this.color = brush;
this.topleft = topleft;
this.lineheight = lineheight;
}


public string text;
public double emSize;
public SolidColorBrush color;

public Point topleft;
public double? lineheight;


private FormattedText _ft;
public FormattedText ft
{
get
{
return _ft;
}
set
{
if (_ft != value)
{
_ft = value;
}
}
}

public event PropertyChangedEventHandler PropertyChanged;
}

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

 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);



}
}

最后,它的效果:

enter image description here

关于c# - 如何在 ItemsControl 中绑定(bind) DataTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25560594/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com