gpt4 book ai didi

Silverlight 的 ItemsControl Canvas.TopProperty 和 Canvas.LeftProperty 未使用

转载 作者:行者123 更新时间:2023-12-03 10:30:43 32 4
gpt4 key购买 nike

我想创建一个 Canvas ,用户可以在其中放置 UI 元素(代表任务)。然后他可以拖动它们以重新排列它们。这些元素包含在作为 DataContext 的 ObservableCollection 中。

我可以设置 Canvas 的 Left 和 Top 属性,但对象位置不受影响。有任何想法吗?

谢谢,

卡雷尔

更新:
忘记 ItemsControl 后代(感谢 Phil):

 public class CustomItemsCollection    : ItemsControl
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
FrameworkElement contentitem = element as FrameworkElement;
// contentitem.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
// contentitem.VerticalAlignment = System.Windows.VerticalAlignment.Top;
Binding leftBinding = new Binding("Left");
leftBinding.Mode = BindingMode.TwoWay;

contentitem.SetBinding(Canvas.LeftProperty, leftBinding);

Binding topBinding = new Binding("Top");
topBinding.Mode = BindingMode.TwoWay;
contentitem.SetBinding(Canvas.TopProperty, topBinding);
base.PrepareContainerForItemOverride(element, item);
}
}

更多信息:

从 usercontrol 派生的绑定(bind)对象会引发异常,因此经过一番谷歌搜索后,我创建了一个 valueconverter:
public class UIElementWrapper : IValueConverter
{
private Dictionary<object, object> CollectionsPool = new Dictionary<object, object>();

#region IValueConverter Members

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is INotifyCollectionChanged && value is IList)
{
((INotifyCollectionChanged)value).CollectionChanged += UIElementWrapper_CollectionChanged;

var result = new ObservableCollection<ProxyObject>();
foreach (var item in (IList)value)
{
result.Add(new ProxyObject(item));
}

CollectionsPool.Add(result, value);
return result;
}
else
{
throw new ArgumentException("value");
}
}

void UIElementWrapper_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (CollectionsPool.ContainsValue(sender))
{
foreach (IList result in CollectionsPool.Keys)
{
if (CollectionsPool[result] == sender)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
var index = e.NewStartingIndex;
foreach (var item in e.NewItems)
{
result.Insert(index++, new ProxyObject(item));
}
break;
case NotifyCollectionChangedAction.Remove:
foreach (var item in e.OldItems)
{
var deleteList = new List<ProxyObject>();
foreach (ProxyObject p in result)
{
if (p.Value == item) deleteList.Add(p);
}
foreach (var p in deleteList)
{
result.Remove(p);
}
}
break;
case NotifyCollectionChangedAction.Replace:
result[e.OldStartingIndex] = new ProxyObject(e.NewItems[0]);
break;
case NotifyCollectionChangedAction.Reset:
result.Clear();
break;
default:
break;
}
}
}
}
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}

#endregion
}

public class ProxyObject
{
public ProxyObject(object value)
{
Value = value;
}
public object Value { get; private set; }
}

这行得通。
但是当我绑定(bind) ObservableCollection 中包含的元素的 Left 和 Top 属性时,它们没有被使用:所有项目都放置在位置 0,0

这是后面的代码:
public MainPage()
{
InitializeComponent();

ObservableCollection<Border> items = new ObservableCollection<Border>();
double left = 0.0;
double top = 0.0;
int i = 0;
Border item = (Border)XamlReader.Load(
"<Border Background=\"Green\" Height=\"140\" Width=\"180\" xmlns=\"http://schemas.microsoft.com/client/2007\"></Border>");
item.Name = string.Format("name {0}", i);
item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);
items.Add(item);

i++;
left += 200;
top += 150;
item = (Border)XamlReader.Load(
"<Border Background=\"Yellow\" Margin=\"160, 120, 0, 0\" Height=\"120\" Width=\"160\" xmlns=\"http://schemas.microsoft.com/client/2007\"></Border>");
item.Name = string.Format("name {0}", i);
item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);
items.Add(item);

i++;
left += 170;
top += 130;
item = (Border)XamlReader.Load(
"<Border Background=\"Red\" Height=\"60\" Width=\"80\" xmlns=\"http://schemas.microsoft.com/client/2007\"></Border>");
item.Name = string.Format("name {0}", i);
item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);
items.Add(item);

left += 90;
top += 70;
item = (Border)XamlReader.Load(
"<Border Background=\"Blue\" Height=\"30\" Width=\"40\" xmlns=\"http://schemas.microsoft.com/client/2007\"></Border>");
item.Name = string.Format("name {0}", i);

item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);
items.Add(item);



try
{
// this.customItemsCollection1.ItemsSource = items;
LayoutRoot.DataContext = items;
}
catch (Exception ex)
{
textBlock1.Text = ex.Message;
}
}

这是xaml:
<UserControl x:Class="ItemsControlTestProject.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lh="clr-namespace:ItemsControlTestProject.Helpers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="560" xmlns:my="clr-namespace:ItemsControlTestProject">


<UserControl.Resources>
<lh:UIElementWrapper x:Key="UIElementWrapper"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="AntiqueWhite">
<my:CustomItemsCollection Canvas.Left="0" Canvas.Top="0" Background="Coral" x:Name="customItemsCollection1" Margin="0,0,0,0" Width="532" ItemsSource="{Binding Converter={StaticResource UIElementWrapper}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="LightGoldenrodYellow" Canvas.Left="0" Canvas.Top="0" Width="350" Height="350"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Value}" Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</my:CustomItemsCollection>
<TextBlock Height="61" Name="textBlock1" Text="TextBlock" AllowDrop="True" Width="526" Canvas.Left="6" Canvas.Top="367" Margin="20,388,14,0" />
</Grid>
</UserControl>





<UserControl.Resources>
<lh:UIElementWrapper x:Key="UIElementWrapper"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="AntiqueWhite">
<my:CustomItemsCollection Canvas.Left="0" Canvas.Top="0" Background="Coral" x:Name="customItemsCollection1" Margin="0,0,0,0" Width="532" ItemsSource="{Binding Converter={StaticResource UIElementWrapper}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="LightGoldenrodYellow" Canvas.Left="0" Canvas.Top="0" Width="350" Height="350"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Value}" Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</my:CustomItemsCollection>
<TextBlock Height="61" Name="textBlock1" Text="TextBlock" AllowDrop="True" Width="526" Canvas.Left="6" Canvas.Top="367" Margin="20,388,14,0" />
</Grid>
</UserControl>

最佳答案

问题是您在绑定(bind)之前设置了依赖属性 Canvas.Top,方法是将其添加到集合中。在此“添加”之前,您要绑定(bind)的对象没有属性 Canvas.Top

只需更改顺序

items.Add(item);
item.SetValue(Canvas.LeftProperty, left);
item.SetValue(Canvas.TopProperty, top);

..它应该工作

/尼克尔

关于Silverlight 的 ItemsControl Canvas.TopProperty 和 Canvas.LeftProperty 未使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3629347/

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