2014-09-25 5 views
0

Я застрял в попытке повторно использовать код макета для своего приложения WPF.Повторное использование макета WPF XAML с привязками?

Я пытаюсь создать редактор XML, который позволяет открывать несколько файлов (через вкладки).

Моя ситуация выглядит следующим образом:

<TabControl> 
    <TabItem> 
    // Layout XAML with various {Binding} sources (File 1) 
    </TabItem> 
    <TabItem> 
    // Layout XAML with various {Binding} sources (File 2) 
    </TabItem> 
    <TabItem> 
    // Layout XAML with various {Binding} sources (File 3) 
    </TabItem> 
</TabControl> 

Это работает; однако каждый из трех TabItems - это огромный кусок копии & вставляемый код, с измененным только несколькими именами, чтобы избежать дублирования имен.

Я хочу переписать код таким образом, что-то вроде этого можно:

<TabControl> 
    <TabItem> 
    // Reference to Template 
    </TabItem> 
    <TabItem> 
    // Reference to Template 
    </TabItem> 
    <TabItem> 
    // Reference to Template 
    </TabItem> 
</TabControl> 

И есть шаблон определен где-то в другом месте.

Я попытался с помощью DataTemplate для шаблона, и присвоив каждому TabItem с ContentTemplate, но хотя макет отображается правильно, все {Наручники} были потеряны.

Я много искал в googled, но не смог понять, как я должен приближаться к этому.

Я бы очень признателен за любые ссылки на демонстрации, которые покажут, как добиться привязки без копирования &.

Я также был бы признателен за любые советы по отладке неудачных привязок, кроме попыток выяснить, пока они не работают. (Мне удобно отлаживать C# с помощью отладчика, но не знаю, как проверить материал XAML)

Заранее благодарим!

+0

Что вы имеете в виду, привязки были потеряны? Шаблон данных что-то не удалит строки привязки (см. Каждое использование одного как «ItemTemplate») – BradleyDotNET

+0

У меня есть XmlDataProvider вне TabControl. Внутри TabControl у меня есть такие вещи, как ItemsSource = "{Binding}. Когда я запускаю программу, данные не отображаются на экране, если я использую шаблон. – Brent

+0

@Brent лучше всего обернуть поведение вкладки в его собственная модель представления. – Crono

ответ

0

Вы должны представить свои элементы табуляции с помощью ObservableCollection, используя ViewModel окна.

<TabControl ItemsSource="{Binding Path=TabItems, Mode=OneTime}" SelectedValue="{Binding Path=SelectedTab, Mode=TwoWay}"> 
    <TabControl.ItemContainerStyle> 
     <Style TargetType="TabItem"> 
      <Setter Property="Header" Value="{Binding Header}"/> 
      <Setter Property="Content" Value="{Binding}"/> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type TabItem}"> 
         <Grid> 
          <Border Name="Border" Margin="0,0,-4,0" BorderThickness="1"> 
           <ContentPresenter 
            x:Name="ContentSite" 
            HorizontalAlignment="Center" 
            Margin="12,2,12,2" 
            VerticalAlignment="Center" 
            ContentSource="Header" 
            RecognizesAccessKey="True"/> 
          </Border> 
         </Grid> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsSelected" Value="True"> 
             etc... 

          </Trigger> 
          <Trigger Property="IsMouseOver" Value="True"> 
             etc... 

          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </TabControl.ItemContainerStyle> 
</TabControl> 

Каждый элемент табуляции будет представлять собой модель представления, содержащую все данные внутри, которые необходимо привязать для каждой вкладки. Так, например:

public ObservableCollection<TabItemViewModel> TabItems 
{ 
    get 
    { 
     return m_SuspendTabItems; 
    } 
    private set 
    { 
     if (Equals(m_SuspendTabItems, value)) 
     { 
      return; 
     } 

     m_SuspendTabItems = value; 

     NotifyPropertyChanged(s_SuspendTabItems); 
    } 
} 

Был бы на вашем основном WindowViewModel. Чтобы добавить новую вкладку, вы просто вызовите TabItems.Add (новый TabItemViewmodel()) ;.

Где «TabItemViewModel» содержит вашу привязку для данного элемента табуляции.

0

Я бы предложил написать пользовательский UserControl, содержащий все, что вы сейчас скопируете, и добавить этот UserControl в элементы табуляции. Добавьте к этому UserControl ваши искомые источники как свойство зависимости. Теперь вы можете получить доступ к нему из своего TabControl без потери привязок.

Я сделал быстрый нерабочий пример:

MyControl.XAML

<UserControl Name=this> 
    <StackPanel> 
     <TextBox Text={Binding Something, ElementName=this} /> 
    </StackPanel> 
</UserControl> 

MyControl.xaml.cs

public partial class MyControl : UserControl 
{ 
    public static readonly DependencyProperty SomethingProperty = DependencyProperty.Register("Something", typeof(string), typeof(MyControl)); 

    public string KeyType 
    { 
     get { return (string)GetValue(SomethingProperty); } 
     set { SetValue(SomethingProperty , value); } 
    } 
} 

program.xaml

<Window> 
    <TabControl> 
     <TabItem> 
      <MyControl Something={Binding Anything[0] /> 
     </TabItem> 
     <TabItem> 
      <MyControl Something={Binding Anything[1] /> 
     </TabItem> 
     //... 
    </TabControl> 
</Window> 

program.xaml.cs

//... 
public string[] Anything { get; set; } 
//... 

Имейте в виду, что это лишь очень простой пример. Вы можете легко добавить свою требуемую модель, как указано выше, в ObservableCollection и автоматически создать элементы табуляции.

Смежные вопросы