C# 如何为ItemsControl创建附加属性
我有下面的ItemsControl,如图所示,它有硬编码的值,我想将这些值转换为一个附加属性,可能是一个ObservableCollection或类似的东西 如何创建此附加属性以及如何绑定它C# 如何为ItemsControl创建附加属性,c#,wpf,xaml,itemscontrol,attached-properties,C#,Wpf,Xaml,Itemscontrol,Attached Properties,我有下面的ItemsControl,如图所示,它有硬编码的值,我想将这些值转换为一个附加属性,可能是一个ObservableCollection或类似的东西 如何创建此附加属性以及如何绑定它 <ItemsControl Grid.Column="0" VerticalAlignment="Stretch" Name="ItemsSelected"> <sys:Double>30</sys:Double> <sys:Double>70
<ItemsControl Grid.Column="0" VerticalAlignment="Stretch" Name="ItemsSelected">
<sys:Double>30</sys:Double>
<sys:Double>70</sys:Double>
<sys:Double>120</sys:Double>
<sys:Double>170</sys:Double>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill="SlateGray" Width="18" Height="4"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
自定义垂直滚动条的样式在窗口中设置。参考资料
该行为是在DataGrid上设置的,如下所示:
<DataGrid Name="GenericDataGrid">
<i:Interaction.Behaviors>
<helpers:DataGridSelectionChanged />
</i:Interaction.Behaviors>
</DataGrid>
我的选择改变了行为:
ScrollBarMarkers.SetMarkersSelectedCollection(ItemsControl, initSelected);
public class DataGridSelectionChanged : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += DataGrid_SelectionChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -= DataGrid_SelectionChanged;
}
void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ObservableCollection<double> initSelected = new ObservableCollection<double>();
initSelected.Add(30);
initSelected.Add(60);
initSelected.Add(100);
//Just trying to figure out how best to get the ItemsControl object.
ScrollBarMarkers.SetMarkersSelectedCollection(itemsControlObj, initSelected);
}
}
下面是滚动条中标记的示例,已根据问题顶部右侧的代码将ItemsControl添加到自定义垂直滚动条中。
如果我理解您的问题,您希望将ObservableCollection绑定到ItemsControl,并且当项目较长时,将显示滚动条 这个解决方案可以为您服务 [我将与MVVM合作] 您可以在代码中创建ObservableCollection
private ObservableCollection<int> _list = new ObservableCollection<int>();
public ObservableCollection<int> List
{
get { return _list ; }
set { _list = value; RaisePropertyChanged("List"); }
}
现在,将集合绑定到ItemsControl
<ScrollViewer HorizontalAlignment="Left" Width="254" Height="Auto" >
<ItemsControl x:Name="ItemsControlComputers" ItemsSource="{Binding List, Mode=TwoWay}" Height="Auto"
HorizontalAlignment="Left" Width="254" ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width="254">
<TextBlock Text="{Binding }" Margin="4,0,0,5" VerticalAlignment="Center">
</TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
如果没有创建DependencyProperty,我应该创建一个普通属性,但是因为它与UI相关,所以我不希望它与ViewModel一起使用。因此,我在与我的行为和其他附加属性相同的命名空间中创建了一个具有singleton模式的类。这也意味着我可以根据任何行为设置集合 以下是装订:
<ItemsControl ItemsSource="{Binding Source={x:Static helpers:MyClass.Instance}, Path=SelectedMarkers}">
这是一个单例模式的类
public class MyClass : INotifyPropertyChanged
{
public static ObservableCollection<double> m_selectedMarkers = new ObservableCollection<double>();
public ObservableCollection<double> SelectedMarkers
{
get
{
return m_selectedMarkers;
}
set
{
m_selectedMarkers = value;
NotifyPropertyChanged();
}
}
private static MyClass m_Instance;
public static MyClass Instance
{
get
{
if (m_Instance == null)
{
m_Instance = new MyClass();
}
return m_Instance;
}
}
private MyClass()
{
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
不需要附加属性。。。只需创建ObservaleCollection并使用类似于创建和填充列表的条目填充它,然后将集合分配/绑定到ItemsControl的ItemsSource属性。还是我误解了你的意图?我可以说得更详细些。我在DataGrid中有一个自定义的垂直滚动条,这个ItemsControl最终将在任何有选定项的地方放置标记。此集合的最佳位置将是作为附加属性,同时还有一些行为将更新集合。我的困惑来自:我没有用ObservaleCollection创建一个附加属性,当绑定到一个属性时,它总是有对象,所以绑定一直是对象属性,这将直接指向原语。但是为什么不能使用ItemsControl.ItemsSource属性呢?我仍然试图理解您的问题的背景-我从您的其他问题中看到,您已经知道如何使用ItemsControl.ItemsSource,因此我想我仍然无法理解您的问题绑定应该是一样的,无论您是否像在您的问题中那样在XAML中指定了项值,或者这些值是否在分配/绑定到ItemsControl的ItemsSource属性的集合中…我想说,尝试使用DP…不完全是这样,如果您查看上面的图像,您将看到垂直滚动条上有标记。这些标记是使用ItemsControl创建的,表示DataGrid中的选定项。因此,您希望将每个元素的滚动条放入ItemsControl?如果您希望滚动条出现,只需将滚动条放入ScrollViewer,即可将DataGrid…不需要ItemsControl。我仍然没有找到DataGrid和ItemsControl之间的关系
public class MyClass : INotifyPropertyChanged
{
public static ObservableCollection<double> m_selectedMarkers = new ObservableCollection<double>();
public ObservableCollection<double> SelectedMarkers
{
get
{
return m_selectedMarkers;
}
set
{
m_selectedMarkers = value;
NotifyPropertyChanged();
}
}
private static MyClass m_Instance;
public static MyClass Instance
{
get
{
if (m_Instance == null)
{
m_Instance = new MyClass();
}
return m_Instance;
}
}
private MyClass()
{
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}