last day (15 days later) » 

1:20 PM
3
A: Список внутри списка в WPF C#

EvgeniyZИ так, для реализации данной задачи нам следует сначала обзавестись неким классом, который мы укажем нашему приложения как некий источник данных для привязки (DataContext), пусть на данный момент это будет пустой класс с названием MyDataClass: public class MyDataClass { } Хорошо. Далее нам на...

 
@EvgeniyZ благодарю за подробные пояснения, в этом разобрался. вопрос, как сделать связь между внешним listbox'ом и внутренним? ну, например, при выделении "боевики", чтобы выбирались все фильмы из этого раздела. после winforms на wpf приходится перестраивать мышление, конечно...
 
@PavelNewSky лучше используйте стандартный TreeView а не изобретайте велосипед без надобности.
 
@FoggyFinder я почти для своих целей всё отработал, осталось только понять, как при выделении, как в примере, "боевики", выделялось всё внутри. а в TreeView нужно тоже разбираться, как туда чекбоксы вставить, как сделать множественный выбор и т.д.
 
@PavelNewSky зависит от того как вы организовали ваши типы данных
 
@FoggyFinder давайте разговаривать в рамках данного ответа. предположим, что у нас есть проект, созданный из кода, скопированного из ответа Евгения.
 
1:20 PM
@PavelNewSky не получится, нужно вместо string перейти к типу данных который будет отвечать за фильм с возможностью выбора. То есть type Film = { Name : string; IsSelected : bool}
 
доброго времени суток, замучался уже с этой проблемой. одно решение проблемы рождает другую. осталось вроде бы одно сделать: выбирая верхний уровень, чтобы выделялись все уровни внутри. но вот не получается у меня. посоветуйте что-нибудь, пожалуйста. даже если TreeView, то можете подсказать как с ним работу. может, ссылки на литературу или статьи.
 
вы имеете ввиду все дочерние элементы, а не уровни?
 
да, дочерние
 
каждый из которых можно отмечать самостоятельно, правильно?
 
да
 
1:26 PM
количество уровней всего два?
 
да
а когда снимаешь галочку на 1 уровне, снимаются все на дочернем(2). вроде задача достаточно типична, так бьюсь полдня
 
хм,так вам нужна обычная группировка
меня смутила картинка в вопросе, думал у вас большая вложенность
 
да я взял первую попавшуюся для примера, не ожидал, что собьет с сути
типа того нужно. только таких элементов может быть много, но уровня всего два.
группировка?
 
да
сейчас попробую написать пример, не страшно если он будет на F#?
 
желательно на c#, но если будет на F#, буду разбираться с этим, у меня все равно вариантов нет других)
 
1:43 PM
крайне редко использую C#; если увижу что много специфического кода получается, то придется менять язык
 
1:55 PM
с группировками непонятно, как выбирать по собственно "группу". хотя получается симпатично: dropmefiles.com/FS6yn
 
а, вы уже нашли информацию самостоятельно?
 
ну что-то накалякал, конечно)) но всё же вопрос остался открытым...как при выделении "type", ну группы, выделить все, что относится к этой группе?
 
2:15 PM
так это самое простое
например, вы в заголовок вывели TxtBlock и хотите по клику мышкой выделить все элементы в списке с этим жанром
<TextBlock
    FontSize="14"
    FontWeight="Bold"
    Text="{Binding Name}">
    <TextBlock.InputBindings>
        <MouseBinding
            Command="{Binding DataContext.Select, ElementName=lv}"
            CommandParameter="{Binding Name}"
            MouseAction="LeftClick" />
    </TextBlock.InputBindings>
</TextBlock>
а в команде Select, если коллекция неизменяемая, то будет что-то вроде такого:
model
|> List.map (fun f -> if f.Genre = genre then {f with IsChoosen = true} else f)
у вас в C# будет что-то вроде такого
var nc = obs.Select(f => f.IsChoose = true).ToArray();
obs.Clear();
foreach(var f in nc)
    obs.Add(f);
(в команде Select)
 
типа удалить всё на втором уровне и добавить заново, но уже с галочками?)
 
да, по другому не получится
(можно конечно взять коллекцию которая оповещает об изменениях своих элементов)
но OS оповещает только о своем изменении
 
а где select прописывается?
 
команда?
в VM
я покажу как это может выглядеть в F# =)
type Message = |Select of string
type VM = { Data:Film list; Select:VmCmd<Message> }
let cvm = { Data=[] ; Select=VmCmd(Select "") }
let fcomponent =
    Component.create<Film list, obj, Message> [
        <@ cvm.Data @> |> Bind.oneWay id
        <@ cvm.Select @> |> Bind.cmdParam Select
    ]

let app nav =
    let model = testData()
    let update message model =
        match message with
        |Select genre ->
            model
            |> List.map (fun f -> if f.Genre = genre then {f with IsChoosen = true} else f)
и
Navigation.singleViewFromWindow Views.MainWin
|> VM.app
|> Framework.RunApplication
 
нашел как добраться через событие "нажатие"
 
2:28 PM
не нужно
вы же следуете MVVM?
 
сейчас попробую реализовать) а F# с первого взгляда очень устрашающе выглядит))
почему? примерно тоже самое
 
так и есть, но через code-behind вы смешиваете отображение и логику
@PavelNewSky я думал выглядит красиво :( так мало кода по сравнению с C#
 
я только начинаю на wpf
и слышал что-то про MVVM
но не следую, видимо)
 
я начинал учить wpf сразу вместе с F# =)
ни разу не пожалел о своем выборе
 
объясните, почему я через отлов событий смешиваю отображение и логику?
я перешел с winforms, а там только там и делал
 
2:32 PM
может я неправильно понял, в примере выше я тоже события использовал
но через MouseBinding
@PavelNewSky в WPF принято, что весь код который отвечает за отображение должен быть в View (в разметке xaml или в связан с конкретным контролом)
например, вы захотели вместо WPF использовать ASP.NET MVC но общий вид оставить тем-же
а у вас галочки ставятся в обработчике события
но если эта логика будет вынесена в часть, которая не связана с интерфейсом, то преимущество сразу становится очевидным
если у вас иммутабельная коллекция то вы можете пойти еще дальше и вынести из VM этот код в Model
 
var nc = obs.Select(f => f.IsChoose = true).ToArray();
obs.Clear();
foreach(var f in nc)
obs.Add(f);
а вот это то где?
 
в команде Select
 
разве не в обработчике событий?
 
нет
 
так, не понимаю, а где прописывать команду select
 
2:38 PM
в VM
возвращаясь к примеру,вот как было:
model
|> List.map (fun f -> if f.Genre = genre then {f with IsChoosen = true} else f)
^ в VM
но мы этот код может безболезненно вынести в Model
написать функцию
let upd xs genre =
    xs
    |> List.map (fun f -> if f.Genre = genre then {f with IsChoosen = true} else f)
и тогда наша update перепишется в виде
let app nav =
    let model = testData()
    let update message model =
        match message with
        |Select genre ->
            upd model genre
а сама функция upd находится в моделе и может даже быть написана на C#
обычно делают наоборот, хотя
 
если честно, я потерялся в том, что вы пишете. если у вас есть время, можете расписать для чайника?
 
сейчас мне нужен перерыв :(
пока написал ответ, возможно в будущем кто-то еще столкнется с той же проблемой
но вообще я каждый день онлайн в F# комнате

 F#

Место для изучения и обучения ; F# Slack Team - fsharp.org/gui...
btw, что именно расписать?
 
2:57 PM
ладно, не буду вас отвлекать) сам почитаю. надеюсь, сейчас найду решение своей проблемы и сдам как есть, а в дальнейшем изучу, как без подобных костылей писать
больше спасибо за потраченное время)
ссылка только в ответе не рабочая
 
 
2 hours later…
4:58 PM
@PavelNewSky рабочая
@PavelNewSky обращайтесь, буду рад помочь
@PavelNewSky я ссылку выше на команды давал. Если у вас есть возможность выложить проект на гитхаб репозиторий, то смогу написать больше
 

last day (15 days later) »