有人可以帮我完成这样的任务。我有资源模板并试图减少其中重复代码的数量
<ControlTemplate x:Key="PlanAssetValue" TargetType="ContentControl">
<ContentControl Template="{StaticResource Period}">
<StackPanel Height="Auto" Width="Auto" x:Name="MainPanel">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Height="Auto"
Margin="10">
<TextBlock Text="{Binding Path=Paramprompt[IsMarket]}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ComboBox DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto"
ItemsSource="{Binding Path=ParamDetails[IsMarket]}"
DisplayMemberPath="Name"
VerticalAlignment="Top"
StaysOpenOnEdit="True"
SelectedValue="{Binding Path=ParamValues[IsMarket]}" SelectedValuePath="Code">
</ComboBox>
</DockPanel>
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Height="Auto"
Margin="10">
<TextBlock Text="{Binding Path=Paramprompt[Currency]}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ComboBox DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto"
ItemsSource="{Binding Path=ParamDetails[Currency]}"
DisplayMemberPath="Name"
VerticalAlignment="Top"
StaysOpenOnEdit="True"
SelectedValue="{Binding Path=ParamValues[Currency]}" SelectedValuePath="Code">
</ComboBox>
</DockPanel>
</StackPanel>
</ContentControl>
</ControlTemplate>
我想将一些文本声明为带有参数的模板,而不是字段IsMarket
<ControlTemplate x:Key="ParamCombobox" TargetType="ContentControl">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Height="Auto"
Margin="10">
<TextBlock Text="{Binding Path=Paramprompt[IsMarket]}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ComboBox DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto"
ItemsSource="{Binding Path=ParamDetails[IsMarket]}"
DisplayMemberPath="Name"
VerticalAlignment="Top"
StaysOpenOnEdit="True"
SelectedValue="{Binding Path=ParamValues[IsMarket]}" SelectedValuePath="Code">
</ComboBox>
</DockPanel>
</ControlTemplate>
答案 0 :(得分:2)
ControleTemplate其逻辑控件的表示。 ContentControl逻辑其当前的一个内容。它有一个名为Content的属性,你可以通过TemplateBinding在模板中使用这个“参数”:{TemplateBinding Content}。
您想要一个代表单个信息的控件。所以创造它!
示例:
class MyUiControl : Control
{
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register("Header", typeof(string), typeof(MyUiControl), new PropertyMetadata(null));
public IEnumerable ItemsCombo
{
get { return (IEnumerable)GetValue(ItemsComboProperty); }
set { SetValue(ItemsComboProperty, value); }
}
public static readonly DependencyProperty ItemsComboProperty =
DependencyProperty.Register("ItemsCombo", typeof(IEnumerable), typeof(MyUiControl), new PropertyMetadata(null));
public object Value
{
get { return (IEnumerable)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(MyUiControl), new PropertyMetadata(null));
}
现在是模板:
<ControlTemplate x:Key="ParamCombobox" TargetType="local:MyUiControl">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Height="Auto"
Margin="10">
<TextBlock Text="{TemplateBinding Header}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ComboBox DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto"
ItemsSource="{TemplateBinding ItemsCombo}"
DisplayMemberPath="Name"
VerticalAlignment="Top"
StaysOpenOnEdit="True"
SelectedValue="{TemplateBinding Value}" SelectedValuePath="Code">
</ComboBox>
</DockPanel>
</ControlTemplate>
和控件:
<local:MyUiControl Header="{Binding paramA}"
ItemsCombo="{Binding paramB}"
Value="{Binding paramC}" />
但是,你真的不需要特殊的逻辑。您的业务只是一组带控件的标签。为此,我认为您可以在模板中使用简单的HeaderedContentControl:
<Style TargetType="HeaderedContentControl">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedContentControl">
<DockPanel>
<TextBlock Text="{TemplateBinding Header}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ContentPresenter DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto" VerticalAlignment="Top" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
控件:
<HeaderedContentControl Header="{Binding paramA}">
<ComboBox ItemsSource="{Binding paramB}"
DisplayMemberPath="Name"
StaysOpenOnEdit="True"
SelectedValue="{Binding paramC}" SelectedValuePath="Code" />
</HeaderedContentControl>
答案 1 :(得分:1)
将这3个相关对象包裹在一个类中,例如
N.B。为简洁起见,我省略了INotifyPropertyChanged
个实现
public class ParamViewModel : INotifyPropertyChanged
{
public string Prompt { get; set; }
public ObservableCollection<string> Details { get; set;}
public string SelectedValue { get; set; }
}
然后让您的控件模板DataContext绑定到父虚拟机中的正确对象:
<ContentControl Template="{StaticResource Period}">
<StackPanel Height="Auto" Width="Auto" x:Name="MainPanel">
<ContentControl DataContext="{Binding Params[IsMarket]}"
Template="{StaticResource ParamTemplate}" />
<ContentControl DataContext="{Binding Params[Currency]}"
Template="{StaticResource ParamTemplate}" />
</StackPanel>
</ContentControl>
您的父虚拟机可能类似于:
public class ParentViewModel : INotifyPropertyChanged
{
public Dictionary<string, Param> Params { get; set;}
}
<ControlTemplate x:Key="ParamTemplate" TargetType="ContentControl">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Height="Auto"
Margin="10">
<TextBlock Text="{Binding Path=Prompt}" DockPanel.Dock="Left" Width="160" Margin="0,2,0,0"/>
<ComboBox DockPanel.Dock="Left" Margin="5,0,0,0" Width="Auto"
ItemsSource="{Binding Path=Details}"
DisplayMemberPath="Name"
VerticalAlignment="Top"
StaysOpenOnEdit="True"
SelectedValue="{Binding SelectedValue}" SelectedValuePath="Code">
</ComboBox>
</DockPanel>
</ControlTemplate>